在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子1、0或 -1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。
以下图表以四列表示四种情况,每行表示在该种情况下要进行的操作。在左左和右右的情况下,只需要进行一次旋转操作;在左右和右左的情况下,需要进行两次旋转操作。
注意:其中左右和右左,先经过一次旋转变为左左和右右的情况,再进行第二次旋转。
可以像普通二叉查找树一样的进行,所以耗费O(log n)时间,因为AVL树总是保持平衡的。不需要特殊的准备,树的结构不会由于查找而改变。(这是与伸展树查找相对立的,它会因为查找而变更树结构。)
#include<iostream> using namespace std; struct TreeNode { int bf; int height; int data; TreeNode *leftchild; TreeNode *rightchild; TreeNode *parent; }; int max(int a, int b) { return a>b?a:b; } template<class obj_s> class AVLTree { public: TreeNode *root; public: AVLTree() { root=NULL; } int getHeight(TreeNode *node); int reComHeight(TreeNode *root);//重新计算高度 //四种旋转方式 TreeNode* LLclockRotation(TreeNode* x); TreeNode* RRantiRotation(TreeNode* x); TreeNode* LRanti_clockRotation(TreeNode* x); TreeNode* RLclock_antiRotation(TreeNode* x); // TreeNode* reBalance(TreeNode* cur,int bf); //插入和删除 TreeNode* insert(TreeNode* curr,TreeNode* prev,int num); TreeNode* findDelPosition(TreeNode* root,int key); // TreeNode* clearTarget(TreeNode* root); // void toPrint(TreeNode* root,int depth=0); //找待删除结点的前驱结点 TreeNode* FindMin(TreeNode* least); }; template<class obj_s> int AVLTree<obj_s>::getHeight(TreeNode* node) { if(node) return node->height; else return -1; } template<class obj_s> int AVLTree<obj_s>::reComHeight(TreeNode* root) { root->height = max(getHeight(root->leftchild), getHeight(root->rightchild)) + 1; root->bf = getHeight(root->leftchild) - getHeight(root->rightchild); return root->bf; } template<class obj_s> TreeNode* AVLTree<obj_s>::LLclockRotation(TreeNode* x) { TreeNode* y = x->leftchild; x->leftchild = y->rightchild; if (y->rightchild) y->rightchild->parent = x; y->rightchild = x; y->parent = x->parent; x->parent = y; reComHeight(x); reComHeight(y); return y; } template<class obj_s> TreeNode* AVLTree<obj_s>::RRantiRotation(TreeNode* x){ TreeNode* y = x->rightchild; x->rightchild = y->leftchild; if (y->leftchild) y->leftchild->parent = x; y->leftchild = x; y->parent = x->parent; x->parent = y; reComHeight(x); reComHeight(y); return y; } template<class obj_s> TreeNode* AVLTree<obj_s>::LRanti_clockRotation(TreeNode* x) { x->leftchild = RRantiRotation(x->leftchild); return LLclockRotation(x); } template<class obj_s> TreeNode* AVLTree<obj_s>::RLclock_antiRotation(TreeNode* x) { x->rightchild = LLclockRotation(x->rightchild); return RRantiRotation(x); } template<class obj_s> TreeNode* AVLTree<obj_s>::reBalance(TreeNode* curr, int bf) { if(abs(bf)<2) return curr; else { if(bf == -2) { if (curr->rightchild->bf>0) return RLclock_antiRotation(curr); else return RRantiRotation(curr); } else if(bf == 2) { if (curr->leftchild->bf < 0) return LRanti_clockRotation(curr); else return LLclockRotation(curr); } } //return NULL; } template<class obj_s> TreeNode* AVLTree<obj_s>::insert(TreeNode* curr, TreeNode* prev, int num){ int x = 0; if (!curr) { curr = (TreeNode*)malloc(sizeof(TreeNode)); curr->data = num; curr->bf = 0; curr->height = 0; curr->parent = prev; curr->leftchild = curr->rightchild = NULL; x = num; } else if(num<(curr->data)) curr->leftchild = insert(curr->leftchild, curr, num); else if(num>(curr->data)) curr->rightchild = insert(curr->rightchild, curr, num); curr=reBalance(curr,reComHeight(curr)); return curr; } template<class obj_s> void AVLTree<obj_s>::toPrint(TreeNode* root, int depth) { if(root->rightchild) toPrint(root->rightchild, depth + 1); for(int i = 0; i< depth; i++) printf("\t"); printf("%d(%d,%d)\n", root->data,root->height, root->bf); if (root->leftchild) toPrint(root->leftchild, depth + 1); } template<class obj_s> TreeNode* AVLTree<obj_s>::FindMin(TreeNode* least){ if(!least->leftchild) return least; else FindMin(least->leftchild); } template<class obj_s> TreeNode* AVLTree<obj_s>::clearTarget(TreeNode* root){ TreeNode* par = root->parent, * temp = root; if (root->leftchild&&root->rightchild){ temp = FindMin(root->rightchild); root->data = temp->data; root->rightchild = findDelPosition(root->rightchild, root->data); } else { if (root->leftchild){ root->leftchild->parent = par; if (par->leftchild == root) par->leftchild = root->leftchild; else if (par->rightchild == root) par->rightchild = root->leftchild; root = root->leftchild; } else if (root->rightchild){ root->rightchild->parent = par;//认可问题 if (par->leftchild == root) par->leftchild = root->rightchild; else if (par->rightchild == root) par->rightchild = root->rightchild; root = root->rightchild; } else root = NULL;//都为NULL free(temp); } if (root) reComHeight(root); return root; } template<class obj_s> TreeNode* AVLTree<obj_s>::findDelPosition(TreeNode* root, int key){ if(key == root->data) root = clearTarget(root); else if(key<root->data) root->leftchild = findDelPosition(root->leftchild, key); else if(key>root->data) root->rightchild = findDelPosition(root->rightchild, key); if(root) root = reBalance(root, reComHeight(root)); return root; } int main() { int temp[10] = { 40, 60, 20, 80, 50, 30, 10, 70, 25,65 }; AVLTree<int> avl; for (int i = 0; i < 10; i++) avl.root = avl.insert(avl.root, avl.root, temp[i]); //avl.findDelPosition(avl.root, 40); 删除操作 avl.toPrint(avl.root); system("pause"); return 0; }