【原理思路】平衡二叉树(AVL树)原理

平衡二叉树,又称AVL树,它可以是一个空树,它也是一颗平衡的二叉搜索树;


AVL树的定义:

(1)定义平衡因子BF,为某节点的左子树的深度和右子树的深度之差;

(2)AVL定义任何的节点的BF,只能是-1,0,1;

(3)任意某节点x的左子树y和右子树z,满足key[y]<=key[x]<=key[z];

(4)包含关键字域key,BF因子域,指向左子女指针left_child,指向右子女指针right_child,指向双亲指针parent,卫星数据data;


AVL树的查找:

(1)从根节点x开始,逐步下降,比较k与key的大小,相同则查找成功直接返回,否则若k<key,则继续查找x的左子树,否则继续查找x的右子树;递归步骤(1);

(2)其实递归的过程就是,一条由树根下降的过程;

(3)最大关键字是沿右子女指针right_child一直到NIL为止所找到的节点;

(4)最小关键字是沿右子女指针left_child一直到NIL为止所找到的节点;

(5)时间复杂度为O(lgn),空间复杂度为O(1);


AVL树的插入:

(1)首先,定义不能插入与原有关键字相同的关键字,如相同,则不能插入;

(2)若是一个空树,直接插入,且该节点为根节点;

(3)插入节点为x,在向下寻找插入位置的过程中,使用指针y始终指向所比较的值z的父节点,比较key(x)和key(z)直到z为NIL,遍历的过程中,判断x是y的左孩子还是右孩子,更新他们的BF因子,插入完成好,要旋转到平衡

(4)由于要保持整棵树的平衡性,但是我们只需要调整插入点至根节点的路径上不满足平衡状态的各节点中深度最大的那个即可。节点y为不平衡的最大BF因子,且当x是y的左子树中;

(4.1)若BF等于-1(右子树的深度大于左子树的深度),将BF的平衡因子改为1;

(4.2)若BF等于0(右子树的深度等于左子树的深度),将BF的平衡因子增为1;

(4.3)若BF等于1(右子树的深度小于左子树的深度),若y的左子树根节点的BF为1,则进行如下(a)图的操作;

y的左子树根节点的BF为-1,则进行如下(b)图的操作;

(5)当x是y的右子树中时;

(5.1)若BF等于-1(右子树的深度大于左子树的深度),将BF的平衡因子改为1;

(5.2)若BF等于0(右子树的深度等于左子树的深度),将BF的平衡因子增为1;

(5.3)若BF等于1(右子树的深度小于左子树的深度),若y的右子树根节点的BF为-1,则进行如下(c)图的操作;

y的右子树根节点的BF为1,则进行如下(d)图的操作;

(6)时间复杂度为O(lgn),空间复杂度为O(1);

《【原理思路】平衡二叉树(AVL树)原理》

《【原理思路】平衡二叉树(AVL树)原理》


AVL树的删除:

(1)要删除的节点是当前根节点T。如果左右子树都非空。在高度较大的子树中实施删除操作。分两种情况:
(1.1)当左子树高度大于右子树高度时,将左子树中最大的那个元素赋给当前根节点,然后按照上述思想,删除左子树中元素值最大的那个节点。
(1.2)当左子树高度小于右子树高度,将右子树中最小的那个元素赋给当前根节点,然后按照上述思想,删除右子树中元素值最小的那个节点。
(1.3)如果左右子树中有一个为空,那么直接用那个非空子树或者是NULL替换当前根节点即可。
(2)要删除的节点元素值小于当前根节点T值,在左子树中进行删除。递归调用,在左子树中实施删除。这个是需要判断当前根节点是否仍然满足平衡条件,如果满足平衡条件,只需要更新当前根节点T的BF因子。否则,需要进行旋转调整:如果T的左子节点的左子树的高度大于T的左子节点的右子树的高度,进行相应的单旋转,否则进行双旋转。
(3)要删除的节点元素值大于当前根节点T值,在右子树中进行删除。过程与上述步骤类似。

    原文作者:AVL树
    原文地址: https://blog.csdn.net/sykpour/article/details/25214543
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞