AVL树的插入和删除

来源:互联网 发布:关口知宏2017来中国 编辑:程序博客网 时间:2024/06/06 00:18

平衡二叉树定义:任一节点的左右子树高度差的绝对值不超过1。
定义BF为平衡因子,HL和HR分别为T的左右子树的高度,满足|BF|<=1。
节点数为n的平衡二叉树的最大高度为O(lgn)。
查找、插入和删除在平均和最坏情况下的时间复杂度都是
O(logn),增加和删除可能需要通过一次或多次树旋转来重新平衡这棵树。
在AVL树中插入一个节点的算法:
(1)若树为空,插入元素作为AVL树的根节点,树的深度增1
(2)若插入元素和根节点值相等,则不进行处理
(3)若插入元素的值小于根节点值,而且在左子树中不存在和插入元素相同的节点,则将元素插入该树的左子树,插入之后左子树的深度增加1,分别就下列不同情况处理:
a,根节点的平衡因子为-2(右子树的深度大于左子树深度,则将平衡因子调整为-1)
b,根节点的平衡因子为2(右子树的深度小于左子树深度,则将平衡因子调整为1)
(4)若插入元素的值大于根节点值,而且在右子树中不存在和插入元素相同的节点,则将元素插入该树的右子树,插入之后右子树的深度增加1,分别就不同情况进行处理。
AVL树的调整策略:
T1, T2, T3 , T4 子树
(1)插入点位于左子树的左子树

这里写图片描述

(2)插入点位于左子树的右子树

这里写图片描述

(3)插入点位于右子树的右子树

这里写图片描述

(4)插入点位于右子树的左子树

这里写图片描述

typedef struct ACLNode *Position;typedef Position AVLTree;struct AVLNode{    ElementType Data;//节点数据    AVLTree Left;//指向左子树    AVLTree Right;//指向右子树    int Height;//树高};int Max(int a, int b){    return a>b ? a : b;}AVLTree SingleLeftRotation(AVLTree A){//A必须有一个右子结点B    AVLTree B = A->Right;    AVLTree C = B->Left;    B->Right = A;    A->Left = C;    A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;    B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;    return B;}AVLTree SingleRightRotation(AVLTree A){//A必须有一个左子结点B    AVLTree B = A->Left;    AVLTree C = B->Right;    B->Right = A;    A->Left = C;    A->Height = Max(GetHeight(A->Left), GetHeight(A->Right))+1;    B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;    return B;}AVLTree DoubleLeftRightRotation(AVLTree A){//A必须有一个左子结点B,且B必须有一个右子结点C,先左移,再右移    A->Left = SingleLeftRotation(A->Left);    return SingleRightRotation(A);}AVLTree DoubleRightLeftRotation(AVLTree A){//A必须有一个右子结点B,且B必须有一个左子结点C,先右移,再左移    A->Right = SingleRightRotation(A->Left);    return SingleLeftRotation(A);}AVLTree Insert(AVLTree T, ElementType X) {    if(!T) {        T = (AVLTree)malloc(sizeof(struct AVLNode));        T->Data = X;        T->Height = 0;        T->Left = T->Right = NULL;    } else if(X < T->Data) {        //插入左子树        T->Left = Insert(T->Left, X);        if (GetHeight(T->Left) - GetHeight(T->Right) == 2) {            if (X < T->Left->Data){//右单旋                T= SingleRightRotation(T);            } else {                T = DoubleLeftRightRotation(T);//左右旋转               }        }    } else if(X > T->Data) {            //插入右子树            T->Right = Insert(T->Right, X);            if(GetHeight(T->Left) - GetHeight(T->Right) == -2) {                if(X > T->Right->Data){                    T = SingleLeftRotation()T;//左单旋                 } else {                    T = SingleRightLeftRotation(T);//右左单旋                }               }    }    T->Height = Max(GetHeight(T->Left), GetHeight(T->Right));    return T;}

AVL树的删除元素同二叉查找树相同,需要删除后调整树的平衡因子,调整过程同插入元素后的调整方式相同。

原创粉丝点击