AVL樹的實現(C++)
阿新 • • 發佈:2019-02-25
同時 ota 等於 左右子樹 sin == double 旋轉 struct
AVL樹,即平衡二叉搜索樹,並且其左右子樹的高度相差小於等於1。
AVL樹的實現,在於插入節點的同時,保持樹的平衡性。共分為如下四種旋轉:
1. 左單邊右旋轉
當在k1的左子樹上插入節點以後,導致K2失去平衡後的旋轉。
代碼實現如下:
/* * * 左單邊向右旋轉 */ void singleRotateWithLeft(AvlNode * & k2) { AvlNode * k1 = k2->left; k2->left = k1->right; k1->right = k2; k2->h = max(h(k2->left), h(k2->right)) + 1; k1->h = max(h(k1->left), h(k1->right)) + 1; k2 = k1; }
2. 右單邊左旋轉
當在K2點右子樹上插入節點後,導致的旋轉,如下圖;
代碼如下:
代碼如下:
/* * * 右單邊向左旋轉 * */ void singleRotateWithRight(AvlNode * & k1) { AvlNode* k2 = k1->right; k1->right = k2->left; k2->left = k1; k1->h = max(h(k1->left), h(k1->right)) + 1; k2->h = max(h(k2->left), h(k2->right)) + 1; k1 = k2; }
3. 左邊2次旋轉:
當在K1的右子樹上插入節點,導致K3失去平衡後的旋轉。此時,需要做2次旋轉。
a. 以K1為根,進行右單邊左旋轉
b. 以K3為根,進行左單邊右旋轉
代碼如下:
/* * * 左單邊向右doube旋轉 */ void doubleRotateWithLeft(AvlNode * & node) { singleRotateWithRight(node->left); singleRotateWithLeft(node); }
4. 右邊2次旋轉
代碼
/* * * 右單邊向左doube旋轉 */ void doubleRotateWithRight(AvlNode * & node) { singleRotateWithLeft(node->right); singleRotateWithRight(node); }
all code :
class MyAVLTree { private: struct AvlNode { int val; AvlNode * left; AvlNode * right; int h; AvlNode(int x) : val(x), h(0), left(NULL), right(NULL) {} }; AvlNode * root; static const int ALLOWED_IMBALANCE = 1; public: MyAVLTree():root(NULL) {} AvlNode * getHead() { return root; } int h(AvlNode * root) { return root == NULL ? 0 : root->h; } void insert(int value) { insert(value, root); } void insert(int value,AvlNode * & node) { if (node == NULL) { node = new AvlNode{value}; } else if (value < node->val) { insert(value, node->left); } else if (value > node->val) { insert(value, node->right); } balance(node); } void balance(AvlNode * & node) { if (node == NULL) { return; } if (h(node->left) - h(node->right) > ALLOWED_IMBALANCE) { if (h(node->left->left) >= h(node->left->right)) { singleRotateWithLeft(node); } else { doubleRotateWithLeft(node); } } else if (h(node->right) - h(node->left) > ALLOWED_IMBALANCE) { if (h(node->right->right) >= h(node->right->left)) { singleRotateWithRight(node); } else { doubleRotateWithRight(node); } } node->h = max(h(node->left), h(node->right)) + 1; } /* * * 左單邊向右旋轉 k2 k1 k1 z ==> x k2 x y y z */ void singleRotateWithLeft(AvlNode * & k2) { AvlNode * k1 = k2->left; k2->left = k1->right; k1->right = k2; k2->h = max(h(k2->left), h(k2->right)) + 1; k1->h = max(h(k1->left), h(k1->right)) + 1; k2 = k1; } /* * * 右單邊向左旋轉 * k1 k2 * x k2 ==> k1 z * y z x y * * */ void singleRotateWithRight(AvlNode * & k1) { AvlNode * k2 = k1->right; k1->right = k2->left; k2->left = k1; k1->h = max(h(k1->left), h(k1->right)) + 1; k2->h = max(h(k2->left), h(k2->right)) + 1; k1 = k2; } /* * * 左單邊向右doube旋轉 */ void doubleRotateWithLeft(AvlNode * & node) { singleRotateWithRight(node->left); singleRotateWithLeft(node); } /* * * 右單邊向左doube旋轉 */ void doubleRotateWithRight(AvlNode * & node) { singleRotateWithLeft(node->right); singleRotateWithRight(node); } int max(int a, int b) { return a > b ? a : b; } void printAvlTreeWithPreOder(AvlNode * node) { if (node == NULL) { return; } cout << node->val << " "; printAvlTreeWithPreOder(node->left); printAvlTreeWithPreOder(node->right); } void printAvlTreeWithInOder(AvlNode * node) { if (node == NULL) { return; } printAvlTreeWithInOder(node->left); cout << node->val << " "; printAvlTreeWithInOder(node->right); } };
AVL樹的實現(C++)