1、AVL树(平衡二叉树)
平衡二叉树的基本思想就是在构建二叉排序树的过程中要让整个树保持平衡。
其定义为:
平衡二叉树或者是空树,或者是满足下列性质的二叉树。
⑴:左子树和右子树深度之差的绝对值不大于1;
⑵:左子树和右子树也都是平衡二叉树。
平衡因子(Balance Factor) :二叉树上结点的左子树的深度减去其右子树
深度称为该结点的平衡因子。
因此,平衡二叉树上每个结点的平衡因子只可能是-1、0和1,否则,只要有一个结点的平衡因子的绝对值大于1, 该二叉树就不是平衡二叉树。
如果一棵二叉树既是二叉排序树又是平衡二叉树,称为平衡二叉排序树
(Balanced Binary Sort Tree) 。
我们希望任何初始序列构成的二叉排序树都是平衡二叉树。因为AVL树上的任何结点的左右子树的深度之差不超过1,则可以证明它的深度和logn是同数量级的(其中n为结点的个数)。由此,它的平均查找长度也和logn是同数量级的。
2、将BST树转化为AVL树
3、在BST树中插入结点并将其转化为AVL树的代码实现
#include <iostream>
#include <cstdlib>
#include <queue>
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
using namespace std;
typedef struct AVLNode{
int item;
int bf; //结点的平衡因子
struct AVLNode *lchild, *rchild;
}AVLNode;
//右旋
void RightRotate(AVLNode **p)
{
AVLNode *lc = (*p)->lchild;
(*p)->lchild = lc->rchild;
lc->rchild = *p;
*p = lc;
}
//左旋
void LeftRotate(AVLNode **p)
{
AVLNode *rc = (*p)->rchild;
(*p)->rchild = rc->lchild;
rc->lchild = *p;
*p = rc;
}
//左平衡处理
void LeftBalance(AVLNode **p)
{
//对以指针p为根节点的二叉树做左平衡处理,本算法结束后
//指针p指向新的结点
AVLNode *lc = (*p)->lchild;
AVLNode *rd = NULL;
switch (lc->bf)
{
case LH:
(*p)->bf = lc->bf = EH;
RightRotate(p); break;
case RH:
rd = lc->rchild;
switch (rd->bf)
{
case LH: (*p)->bf = RH; lc->bf = EH; break;
case EH: (*p)->bf = lc->bf = EH; break;
case RH: (*p)->bf = EH; lc->bf = LH; break;
}
rd->bf = EH;
LeftRotate(&((*p)->lchild));
RightRotate(p);
}
}
//右平衡处理
void RightBalance(AVLNode **p)
{
AVLNode *rc = (*p)->rchild;
AVLNode *ld = NULL;
switch (rc->bf)
{
case RH:
(*p)->bf = rc->bf = EH;
LeftRotate(p); break;
case LH:
ld = rc->lchild;
switch (ld->bf)
{
case LH: (*p)->bf = EH; rc->bf = RH; break;
case EH: (*p)->bf = rc->bf = EH; break;
case RH: (*p)->bf = LH; rc->bf = EH; break;
}
ld->bf = EH;
RightRotate(&((*p)->rchild));
LeftRotate(p);
}
}
//创建节点
AVLNode *CreateNode(int item)
{
AVLNode *node = (AVLNode *)malloc(sizeof(AVLNode));
if (node == NULL)
{
cout << "malloc failed!" << endl;
exit(1);
}
node->item = item;
node->lchild = NULL;
node->rchild = NULL;
node->bf = EH;
return node;
}
//插入结点
int InsertAVL(AVLNode **p, int item, bool *taller)
{
//p指目前AVL树的树根
//item为新节点的数据元素
//taller用作旋转处理,反应p的长高与否
if (*p == NULL) //插入节点,树长高,置taller为true
{
*p = CreateNode(item);
*taller = true;
}
else
{
AVLNode *pr = *p;
if (item == pr->item)
{
*taller = false;
return 0;
}
else if (item < pr->item)
{
if (!InsertAVL(&(pr->lchild), item, taller))
return 0;
if (*taller)
{
switch (pr->bf)
{
case LH:
LeftBalance(&pr); *taller = false; break;
case EH:
pr->bf = LH; *taller = true; break;
case RH:
pr->bf = EH; *taller = false; break;
}
}
}
else
{
if (!InsertAVL(&(pr->rchild), item, taller))
return 0;
if (*taller)
{
switch (pr->bf)
{
case LH:
pr->bf = EH; *taller = false; break;
case EH:
pr->bf = RH; *taller = true; break;
case RH:
RightBalance(&pr); *taller = false; break;
}
}
}
*p = pr;
}
return 1;
}
//层次遍历
void indexPrint(AVLNode *p)
{
if (p == NULL)
{
cout << "tree is NULL" << endl;
return;
}
AVLNode *pr = p;
queue<AVLNode *> qa;
qa.push(p);
do
{
if (!qa.empty())
{
pr = qa.front();
qa.pop();
}
cout << pr->item << " " << pr->bf << endl;
if (pr->lchild != NULL)
{
qa.push(pr->lchild);
}
if (pr->rchild != NULL)
{
qa.push(pr->rchild);
}
} while (!qa.empty());
}
int main()
{
AVLNode *tree = NULL;
bool taller;
int arr[] = { 13, 24, 37, 90, 53, 53};
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++)
{
InsertAVL(&tree, arr[i], &taller);
}
indexPrint(tree);
return 0;
}