AVL樹爲什會出現?
我們之前有學習使用二叉查找樹,但是二叉查找樹在使用的時候也會出現一些問題,當恰好所有的數據都是按照大小順序插入的話,就有可能將我們的二叉樹編程鏈表,就導致樹結構退化爲鏈表結構。
什麼是不平衡
其實不平衡就是一個節點下面的左子樹和右子樹的高度相差太多,沒有雨露均沾,導致出現了不平衡的現象。
如何解決不平衡?
其實我們從局部看,不平衡的情況其實就歸爲四種。
- 左—左類型
其實對於這種情況,三個節點都連在左邊,可以使用右旋的方式來調整,以5爲終點將其向右旋轉,然後9向下成爲5的右節點。如果5這個節點有右節點的話,可以按照這樣的方式移動
- 右-右類型
這個也不用多說,都是類似的使用左旋的方式,我們首先先寫出右旋和左旋的代碼。class Node { public: Node * left; Node * right; int height; //需要記錄一下高度 }; class AVLTree { public: AVLTree(){}; ~AVLTree(){}; /*** R_Rotate穿進來的是那個有問題的節點 ***/ Node* R_Rotate(Node * pa) { Node *leftNode = pa -> left; // 講leftNode拿出來 pa -> right = leftNode -> right; leftNode -> right = pa; //重新計算節點的高度 pa->height = getHeight(pa->left) > getHeight(pa->right) ? getHeight(pa->left) : getHeight(pa->right) ; pa->height ++; leftNode->height = getHeight(leftNode->left) > getHeight(leftNode->right) ? getHeight(leftNode->left) : getHeight(leftNode->right) ; leftNode->height ++; return leftNode; } Node * L_Rotate(Node * pa) { Node * R = pa->right; pa -> right = R -> left; R -> left = pa; //重新計算節點的高度 pa->height = getHeight(pa->left) > getHeight(pa->right) ? getHeight(pa->left) : getHeight(pa->right) ; pa->height ++; R->height = getHeight(R->left) > getHeight(R->right) ? getHeight(R->left) : getHeight(R->right) ; R->height ++; return R; } int getHeight(Node * node) { if(node) return node->height; return -1; } Node* L_R_Rotate(Node * pa) { pa->right = L_Rotate(pa -> right); pa = R_Rotate(pa); return pa; } Node* R_L_Rotate(Node* pa) { pa->left = R_Rotate(pa->left); pa = L_Rotate(pa); return pa; } //insert這裏需要使用遞歸,因爲我們需要從上到下進行調整 Node * Insert(Node * newNode,Node * T) { if(!T) { T = newNode; } else if(newNode->val > T->val) { T -> right = Insert(newNode , T -> right); //往右子樹上面插入 if(height(T->right) - height(T->left) == 2) { // right right if(T ->right->val < newNode -> val) { T = L_Rotate(T); } else //right left{ T = L_R_Rotate(T); } } } else if(newNode->val < T -> val) { T -> left = Insert(newNode, T->left); if(height(T->left) - height(T->right) == 2) { // left left if(T->left->val > newNode->val) { T = R_Rotate(T); } else // left right { T = R_L_Rotate(T); } } } T->height = getHeight(T->left) > getHeight(T->right) ? getHeight(T->left) : getHeight(T->right) ; return T; } private: Node * head; };