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; };