AVL树删除算法 (使用树高)

以下代码大部分直接搬运自Mark Allen 的数据结构与算法分析, 略有改动。

鉴于书本及示例代码均未提及删除操作, 在此提供一种思路。


头文件:

//avltree.h
typedef int ElementType;

#ifndef _AVLTREE_H_
#define _AVLTREE_H_

struct AvlNode;
typedef AvlNode * AvlTree;
typedef AvlNode * Position;

AvlTree CreateAvlTree(void);
AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X, AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X, AvlTree T);
AvlTree Delete(ElementType X, AvlTree T);
ElementType Retrieve(Position P);

#endif // _AVLTREE_H_

实现:
//avltree.c
#include<stdlib.h>
#include"avltree.h"
#include"fatal.h"

struct AvlNode{
    ElementType Element;
    AvlTree Left;
    AvlTree Right;
    int Height;
};

static int Height(Position P)
{
    if (P == NULL)
        return -1;
    else
        return P->Height;
}

static int Max(int Lhs, int Rhs)
{
    return Lhs > Rhs ? Lhs : Rhs;
}

static AvlTree SingleRotateWithLeft(Position K2)
{
    Position K1;

    K1 = K2->Left;
    K2->Left = K1->Right;
    K1->Right = K2;

    K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    K1->Height = Max(Height(K1->Left), K2->Height) + 1;

    return K1;
}

static AvlTree SingleRotateWithRight(Position K2)
{
    Position K1;

    K1 = K2->Right;
    K2->Right = K1->Left;
    K1->Left = K2;

    K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    K1->Height = Max(Height(K1->Right), K2->Height) + 1;

    return K1;
}

static AvlTree DoubleRotateWithLeft(Position K3)
{
    SingleRotateWithRight(K3->Left);

    return SingleRotateWithLeft(K3);
}

static AvlTree DoubleRotateWithRight(Position K3)
{
    SingleRotateWithLeft(K3->Right);

    return SingleRotateWithRight(K3);
}

AvlTree CreateAvlTree(void)
{
    return NULL;
}

AvlTree MakeEmpty(AvlTree T)
{
    if (T != NULL)
    {
        MakeEmpty(T->Left);
        MakeEmpty(T->Right);
        free(T);
    }
    return NULL;
}

Position Find(ElementType X, AvlTree T)
{
    if (T == NULL)
        return NULL;
    if (X < T->Element)
        return Find(X, T->Left);
    else if (X > T->Element)
        return Find(X, T->Right);
    else
        return T;
}

Position FindMin(AvlTree T)
{
    if (T != NULL)
        while (T->Left != NULL)
            T = T->Left;
    return T;
}

Position FindMax(AvlTree T)
{
    if (T != NULL)
        while (T->Right != NULL)
            T = T->Right;
    return T;
}

ElementType Retrieve(Position P)
{
    return P->Element;
}

AvlTree Insert(ElementType X, AvlTree T)
{
    if (T == NULL)
    {
        T = malloc(sizeof(struct AvlNode));
        if (T == NULL)
            Error("Out of space");
        T->Element = X;
        T->Left = T->Right = NULL;
        T->Height = 0;
    }
    else if (X < T->Element)
    {
        T->Left = Insert(X, T->Left);
        if (Height(T->Left) - Height(T->Right) == 2)
            if (X < T->Left->Element)
                SingleRotateWithLeft(T);
            else
                DoubleRotateWithLeft(T);
    }
    else if (X > T->Element)
    {
        T->Right = Insert(X, T->Right);
        if (Height(T->Right) - Height(T->Left) == 2)
            if (X > T->Right->Element)
                SingleRotateWithRight(T);
            else
                DoubleRotateWithRight(T);
    }

    T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    return T;
}


/*以下为删除操作*/

static AvlTree DeleteNode(AvlTree T, Position P)
{
    if (P == NULL)
    {
        P = T->Left;
        free(T);
        return P;
    }
    if (P->Left == NULL)
    {
        P->Left = T->Left;
        free(T);
        if (Height(P->Left) - Height(P->Right) == 2)
            if (Height(P->Left->Left) - Height(P->Right) == 1)
                P = SingleRotateWithLeft(P);
            else
                P = DoubleRotateWithLeft(P);
        return P;
    }
    if (P->Left->Left == NULL)
    {
        P->Left->Left = T->Left;
        P->Left->Right = T->Right;
        free(T);
        return P;
    }
    else
    {
        T = DeleteNode(T, P->Left);
        if (Height(P->Right) - Height(P->Left) == 2)
            if (Height(P->Right->Right) - Height(P->Left) == 1)
                P = SingleRotateWithRight(P);
            else
                P = DoubleRotateWithRight(P);
        P->Height = Max(Height(P->Left), Height(P->Right)) + 1;
        return T;
    }
}

AvlTree Delete(ElementType X, AvlTree T)
{
    if (T == NULL)
        return NULL;
    if (X < T->Element)
    {
        if (T->Left = Delete(X, T->Left) == NULL)
            return NULL;
        if (Height(T->Right) - Height(T->Left) == 2)
            if (Height(T->Right->Right) - Height(T->Left) == 1)
                T = SingleRotateWithRight(T);
            else
                T = DoubleRotateWithRight(T);
        T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    }
    else if (X > T->Element)
    {
        if (T->Right = Delete(X, T->Right) == NULL)
            return NULL;
        if (Height(T->Left) - Height(T->Right) == 2)
            if (Height(T->Left->Left) - Height(T->Right) == 1)
                T = SingleRotateWithLeft(T);
            else
                T = DoubleRotateWithLeft(T);
        T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    }
    else if (X == T->Element)
    {
        return DeleteNode(T, T->Right);
    }
    return T;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * AVL树 * 基于BSTree的扩充 */ package dsa; public class AVLTree extends BSTree implements Dictionary { /**************************** 构造方法 ****************************/ public AVLTree() { super(); } public AVLTree(BinTreePosition r) { super(r); } public AVLTree(BinTreePosition r, Comparator c) { super(r, c); } /**************************** 词典方法(覆盖父类BSTree) ****************************/ //插入条目(key, value),并返回该条目 public Entry insert(Object key, Object value) { Entry e = super.insert(key, value);//调用父类方法完成插入 root = rebalance(lastV.getParent(), root);//从插入节点的父亲开始重新平衡化 return e; } //若词典中存在以key为关键码的条目,则将摘除其中的一个并返回;否则,返回null public Entry remove(Object key) { Entry e = super.remove(key);//调用父类方法完成删除 if (null != e) root = rebalance(lastV, root);//从删除节点的父亲开始重新平衡化 return e; } /**************************** 辅助方法 ****************************/ //从节点z开始,自上而下重新平衡化 //返回后,root仍为平衡后的(整棵)的根节点 protected static BinTreePosition rebalance(BinTreePosition z, BinTreePosition r) { if (null == z) return r; while (true) {//从z开始,向上逐一检查z的祖先 if (!isBalanced(z)) rotate(z);//若z节点失去平衡,则通过旋转使之重新平衡 if (!z.hasParent()) return z; z = z.getParent();//继续检查其父亲 }//while } //判断节点v是否平衡 protected static boolean isBalanced(BinTreePosition v) { if (null == v) return true; int lH = (v.hasLChild()) ? (v.getLChild().getHeight()) : -1; int rH = (v.hasRChild()) ? (v.getRChild().getHeight()) : -1; int deltaH = lH - rH; return (-1 <= deltaH) && (deltaH <= 1); } //通过旋转,使节点z的平衡因子的绝对值不超过1(支持AVL树) //返回新的子根 public static BinTreePosition rotate(BinTreePosition z) { BinTreePosition y = tallerChild(z);//取y为z更高的孩子 BinTreePosition x = tallerChild(y);//取x为y更高的孩子 boolean cType = z.isLChild();//记录:z是否左孩子 BinTreePosition p = z.getParent();//p为z的父亲 BinTreePosition a, b, c;//自左向右,三个节点 BinTreePosition t0, t1, t2, t3;//自左向右,四棵子 /******** 以下分四种情况 ********/ if (y.isLChild()) {//若y是左孩子,则 c = z; t3 = z.getRChild(); if (x.isLChild()) {//若x是左孩子 b = y; t2 = y.getRChild(); a = x; t1 = x.getRChild(); t0 = (BSTreeNode)x.getLChild(); } else {//若x是右孩子 a = y; t0 = y.getLChild(); b = x; t1 = x.getLChild(); t2 = (BSTreeNode)x.getRChild(); } } else {//若y是右孩子,则 a = z; t0 = z.getLChild(); if (x.isRChild()) {//若x是右孩子 b = y; t1 = y.getLChild(); c = x; t2 = x.getLChild(); t3 = (BSTreeNode)x.getRChild(); } else {//若x是左孩子 c = y; t3 = y.getRChild(); b = x; t1 = x.getLChild(); t2 = (BSTreeNode)x.getRChild(); } } //摘下三个节点 z.secede(); y.secede(); x.secede(); //摘下四棵子 if (null != t0) t0.secede(); if (null != t1) t1.secede(); if (null != t2) t2.secede(); if (null != t3) t3.secede(); //重新链接 a.attachL(t0); a.attachR(t1); b.attachL(a); c.attachL(t2); c.attachR(t3); b.attachR(c); //子重新接入原 if (null != p) if (cType) p.attachL(b); else p.attachR(b); return b;//返回新的子根 }//rotate //返回节点p的孩子中的更高者 protected static BinTreePosition tallerChild(BinTreePosition v) { int lH = v.hasLChild() ? v.getLChild().getHeight() : -1; int rH = v.hasRChild() ? v.getRChild().getHeight() : -1; if (lH > rH) return v.getLChild(); if (lH < rH) return v.getRChild(); if (v.isLChild()) return v.getLChild(); else return v.getRChild(); } //返回节点p的孩子中的更矮者 protected static BinTreePosition shorterChild(BinTreePosition v) { int lH = v.hasLChild() ? v.getLChild().getHeight() : -1; int rH = v.hasRChild() ? v.getRChild().getHeight() : -1; if (lH > rH) return v.getRChild(); if (lH < rH) return v.getLChild(); if (v.isLChild()) return v.getRChild(); else return v.getLChild(); } }
AVL树是一种自平衡的二叉搜索,它的查找算法时间复杂度为O(log n),其中n是中节点的数量。 AVL树通过在插入或删除节点时进行旋转操作来保持的平衡性。在AVL树中,每个节点都有一个平衡因子,它表示该节点的左子树高度与右子树高度之差。当插入或删除节点后,如果某个节点的平衡因子超过了1或-1,就需要进行旋转操作来恢复平衡。 由于AVL树保持了的平衡性,所以在最坏情况下,AVL树的高度为O(log n)。因此,查找操作的时间复杂度为O(log n)。 下面是一个AVL树的查找算法的示例代码: ```python class Node: def __init__(self, key): self.key = key self.left = None self.right = None self.height = 1 class AVLTree: def __init__(self): self.root = None def insert(self, key): self.root = self._insert(self.root, key) def _insert(self, root, key): if root is None: return Node(key) elif key < root.key: root.left = self._insert(root.left, key) else: root.right = self._insert(root.right, key) root.height = 1 + max(self._get_height(root.left), self._get_height(root.right)) balance = self._get_balance(root) if balance > 1 and key < root.left.key: return self._rotate_right(root) if balance < -1 and key > root.right.key: return self._rotate_left(root) if balance > 1 and key > root.left.key: root.left = self._rotate_left(root.left) return self._rotate_right(root) if balance < -1 and key < root.right.key: root.right = self._rotate_right(root.right) return self._rotate_left(root) return root def _get_height(self, root): if root is None: return 0 return root.height def _get_balance(self, root): if root is None: return 0 return self._get_height(root.left) - self._get_height(root.right) def _rotate_left(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self._get_height(z.left), self._get_height(z.right)) y.height = 1 + max(self._get_height(y.left), self._get_height(y.right)) return y def _rotate_right(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self._get_height(z.left), self._get_height(z.right)) y.height = 1 + max(self._get_height(y.left), self._get_height(y.right)) return y def search(self, key): return self._search(self.root, key) def _search(self, root, key): if root is None or root.key == key: return root if key < root.key: return self._search(root.left, key) return self._search(root.right, key) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值