创建平衡二叉树(AVL树)

首先感谢两位博主的引导:

http://www.cppblog.com/cxiaojia/archive/2012/08/20/187776.html

http://blog.chinaunix.net/uid-24948645-id-3913917.html

以下内容很多是来自上两篇博客的内容,外加自己的实现测试。

AVL树的历史或简介我就不具体描述了,主要讲述以下其实现的原理和测试的结果。

首先要知道的是AVL树对每一个节点都维护着一个平衡因子,要求每个节点的平衡因子为0-11,这样才表示该节点满足平衡。(平衡因子=左子树的高度 右子树的高度

AVL树的节点的每一次插入后,都需要判断该树是否平衡,若不满足,则需要调整。

该测试中树节点的定义结构如下:

struct BSTNode
{
int data;
int height;
BSTNode *lchild;
BSTNode *rchild;
};

AVL的调整主要分为以下四种方式(注:调整前后,树的中序遍历结果不变):

1、在K2节点的左孩子(K1)的左子树插入。K1

创建平衡二叉树(AVL树)_第1张图片

左左调整:

void modifiedLL(BSTNode *&A)
{
BSTNode *B;
B = A->lchild;
A->lchild = B->rchild;
B->rchild = A;
A->height = Max(Height(A->lchild),Height(A->rchild))+1;
B->height = Max(Height(B->lchild),Height(B->rchild))+1;
A = B;
}

2 、在 K2 节点的右孩子( K1 )的右子树插入。 K1


创建平衡二叉树(AVL树)_第2张图片

右右调整:

void modifiedRR(BSTNode *&A)
{
BSTNode *B;
B = A->rchild;
A->rchild = B->lchild;
B->lchild = A;
A->height = Max(Height(A->lchild),Height(A->rchild))+1;
B->height = Max(Height(B->lchild),Height(B->rchild))+1;
A = B;
}

 3、在K3的左孩子(K1)的右子树插入。第一次对K1进行右旋变换,第二次对K3进行左旋变换。

创建平衡二叉树(AVL树)_第3张图片

左右调整:

void modifiedLR(BSTNode *&A)
{
modifiedRR(A->lchild);
modifiedLL(A);
}

4、在K3的右孩子(K1)的左子树插入。第一次对K1进行左旋变换,第二次对K3进行右旋变换。

创建平衡二叉树(AVL树)_第4张图片

右左调整:

void modifiedRL(BSTNode *&A)
{
modifiedLL(A->rchild);
modifiedRR(A);
 
}

依次插入节点代码如下:

BSTNode* Insert(BSTNode *A,int dt)
{
if (A== NULL)
{
A = new BSTNode;
A->height = 0;
A->data = dt;
A->lchild = A->rchild = NULL;
}
else
{
if (dt < A->data)
{
A->lchild = Insert(A->lchild,dt);
if (Height(A->lchild)-Height(A->rchild)==2)
{
if (dt < A->lchild->data)
{
modifiedLL(A);
}
else
{
modifiedLR(A);
}
}
}
else
if(dt > A->data)
{
A->rchild = Insert(A->rchild,dt);
if (Height(A->rchild)-Height(A->lchild)==2)
{
if (dt > A->rchild->data)
{
modifiedRR(A);
}
else
{
modifiedRL(A);
}
}
}
}
A->height = Max(Height(A->lchild),Height(A->rchild))+1;
    return A;
}

最后附上本次创建AVL树的测试结果:

(测试的内容为对16个输入的数据创建AVL树,然后打印出其中序、先序遍历结果)


下图为中序、先序遍历结果最终确定的二叉树形态:

创建平衡二叉树(AVL树)_第5张图片



你可能感兴趣的:(数据结构)