特点:平衡二叉树要求对于每一个节点来说,他的左右子树的高度之差不超过1,如果插入或者删除一个结点使得高度之差大于1,就要进行节点之间的旋转(左旋或者右旋),将二叉树重新维持在一个平衡状态。
解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最坏和最好情况都维持在O(logN)。
旋转缺点:频繁旋转会牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了许多。
平衡二叉树的核心:
旋转算法
1:左左形式的不平衡
2.左右形式的不平衡
3.右左形式的不平衡
4.右右形式的不平衡
1,4一组
2,3一组
对于1:左旋 3的右子树给6的左边,6变成3的右子树,3成根
确定要换的根root和左子树left,left的右子树给root的左,root变成left的右
对于4:右旋 4的左子树给2的右边,2变成4的左子树,2成根
确定要换的根root和右子树right,right的左子树给root的右然后root变成right的左
对于2:先右旋左子树,再左旋根
对于3:先左旋右子书,再右旋根
代码如下:
#include <iostream>
#include <malloc.h>
#include <stack>
using namespace std;
typedef struct TreeNode
{
int height;
int data;
TreeNode* leftC;
TreeNode* rightC;
}TreeNode;
int getHeight(TreeNode* s)
{
if (s != NULL)
{
return s->height;
}
return -1;
}
void InitTree(TreeNode** list)
{
*list = (TreeNode*)malloc(sizeof(TreeNode));
(*list)->height = 0;
(*list)->leftC = NULL;
(*list)->rightC = NULL;
}
void leftRotate(TreeNode*& root)//左左
{
TreeNode *l1 = root;
TreeNode *l2 = root->leftC;
l1->leftC = l2->rightC;
l2->rightC = l1;
l1->height = (getHeight(l1->leftC) > getHeight(l1->rightC) ? getHeight(l1