平衡二叉树之AVL树
AVL树(命名来源于作者姓名,Adelson-Velskii和Landis),即平衡二叉树,满足以下的条件:
1)它的左子树和右子树都是AVL树
2)左子树和右子树的高度差不能超过1
从条件1可能看出是个递归定义。
AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。
AVL树插入节点的步骤,分为2类:
第1类:外侧插入,单旋转
第2类:内侧插入,双旋转(先旋转成外侧插入的情况,再单旋转)
由于调整以后,树高与插入前是相同的,所以无需再向上查看balance情况
代码实现:http://blog.chinaunix.net/uid-20662820-id-142440.html
struct node { node* parent; node* left; node* right; int balance; //左右子树高度之差 int key; }; int searchNode(int key, node* root, node** parent) //如果没找到,parent也是指向要插入位置的父位置 { node* temp; assert(root != NULL); temp = root; *parent = root->parent; while (temp !=NULL) { if (temp->key == key) return 1; else { *parent = temp; if (temp->key > key) temp = temp->left; else temp = temp->right; } } return 0; } node* adjustAVL(node* root, node* parent, node* child) { node *cur; assert((parent != NULL)&&(child != NULL)); switch (parent->balance) { case 2: if (child->balance == -1)//LR型(内侧插入):插入的节点的父节点直接升级做parent { cur = child->right; cur->parent = parent->parent; child->right = cur->left; if (cur->left != NULL) cur->left->parent = child; parent->left = cur->right; if (cur->right != NULL) cur->right->parent = parent; cur->left = child; child->parent = cur; cur->right = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = cur; else parent->parent->right = cur; else root = cur; parent->parent = cur; if (cur->balance == 0) { parent->balance = 0; child->balance = 0; } else if (cur->balance == -1) { parent->balance = 0; child->balance = 1; } else { parent->balance = -1; child->balance = 0; } cur->balance = 0; } else //LL型(外侧插入):插入的节点的父节点升级做child,child升级做parent child->parent = parent->parent; parent->left = child->right; if (child->right != NULL) child->right->parent = parent; child->right = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = child; else parent->parent->right = child; else root = child; parent->parent = child; if (child->balance == 1) //插入时 { child->balance = 0; parent->balance = 0; } else //删除时 { child->balance = -1; parent->balance = 1; } } break; case -2: if (child->balance == 1) //RL型 { cur = child->left; cur->parent = parent->parent; child->left = cur->right; if (cur->right != NULL) cur->right->parent = child; parent->right = cur->left; if (cur->left != NULL) cur->left->parent = parent; cur->left = parent; cur->right = child; child->parent = cur; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = cur; else parent->parent->right = cur; else root = cur; parent->parent = cur; if (cur->balance == 0) { parent->balance = 0; child->balance = 0; } else if (cur->balance == 1) { parent->balance = 0; child->balance = -1; } else { parent->balance = 1; child->balance = 0; } cur->balance = 0; } else //RR型 { child->parent = parent->parent; parent->right = child->left; if (child->left != NULL) child->left->parent = parent; child->left = parent; if (parent->parent != NULL) if (parent->parent->left == parent) parent->parent->left = child; else parent->parent->right = child; else root = child; parent->parent = child; if (child->balance == -1) //插入时 { child->balance = 0; parent->balance = 0; } else //删除时 { child->balance = 1; parent->balance = -1; } } break; } return root; } node* insertNode(int key, node* root) { node *parent, *cur, *child; assert (root != NULL); if (searchNode(key, root, &parent)) //结点已存在 return root; else { cur = (node*)malloc(sizeof(node)); cur->parent = parent; cur->key = key; cur->left = NULL; cur->right = NULL; cur->balance = 0; if (keykey) { parent->left = cur; child = parent->left; } else { parent->right = cur; child = parent->right; } while ((parent != NULL)) //查找需要调整的最小子树 { if (child == parent->left) if (parent->balance == -1) { parent->balance = 0; return root; } else if (parent->balance == 1) { parent->balance = 2; break; } else { parent->balance = 1; child = parent; parent = parent->parent; } else if (parent->balance == 1) //是右孩子,不会引起不平衡 { parent->balance = 0; return root; } else if (parent->balance == -1) //是右孩子,并且引起parent的不平衡 { parent->balance = -2; break; } else //是右孩子,并且可能引起parent的parent的不平衡 { parent->balance = -1; child = parent; parent = parent->parent; } } if (parent == NULL) return root; return adjustAVL(root, parent, child); } }