AVL树(平衡二叉树)

 

 

 

今晚分享平衡二叉树  所以下午预习了一下

还有红黑树  不过目前脑袋有点炸,晚上或者明天再看吧

好 下面开始

首先说明自己的参考来源:点击这里

学习平衡二叉树之前,先学习二叉排序树。

BST

二叉排序树(Binary Sort Tree)又称二叉查找树。

它或者是一棵空树;或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

举一个例子理解一下

创建的结构体如下:

typedef struct _BitNode
{
    int data;
    struct _BitNode *lchild,*rchild;
}BitNode,*BiTree;

左右子树的指针和节点的值。

查找的时候从根节点开始,根据大小查询左右子树。

直到查询为空或查询到目标节点

具体增删改查等操作移步上面参考的文档进行查看

 

AVL

下来说明平衡二叉树

平衡二叉树定义(AVL):

它或者是一颗空树,或者具有以下性质的二叉树:

它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,

且它的左子树和右子树都是一颗平衡二叉树。

定义:平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1

定义结构体

typedef struct _BitNode
{
    int data;
    int bf;//平衡因子
    struct _BitNode *lchild,*rchild;
}BitNode,*BiTree;

平衡二叉树的目的是为了减低操作时间复杂度

下面用两张图比较就可以很好理解了

同样查询10这个节点  图一(AVL)一定是比图二(BST)要快的

平衡二叉树的主要操作分为左旋和右旋

根本目的是在不改变二叉排序树的前提下,把其改成AVL 同时也在插入和删除操作后进行格式的恢复

这个图节点4的深度为2需要进行右旋操作:

让4节点的左孩子指向3的右子树(此时为NULL),让3的右孩子指向4,让树根指向3

代码

void R_Rotate(BiTree&T)
{
    BiTree p;             //
    p=T->lchild;    //假如此时T指向4,则p指向3;
    T->lchild=p->rchild; //把3的右子树挂接到4的左子树上(此例子3右子树为空)
    p->rchild=T;       //让3的右孩子指向4.
    T=p;        //根指向节点3
}

最终结果:

 

 下一个例子:

图中标识有点错误,3节点的平衡因子是-3

这里我们修改平衡因子为-2的节点  进行左旋操作

那我们就把4的右孩子7的左子树(此时为NULL),让7的左孩子指向4,让3的右孩子指向7

最终结果:

 

 

接下来说明一种特殊情况

 

 在这个树的基础上增加10这个节点

这样显然是不对的

进行左旋操作

咦   更不对了! 10怎么跑到11的右边了

BUG!

其实不是的,大家注意到9的平衡因子-2 、10的平衡因子1

符号不同的情况下就会出现错误

我们应先修改11的符号

首先对11进行右旋,再对9进行左旋

Over

 

剩下的代码找之前那个参考的吧

以上是我个人理解,有问题请留言,看到后会尽快回复

一同交流进步。

 

posted on 2018-02-07 17:48  梦林``ysl  阅读(203)  评论(0编辑  收藏  举报

导航