• AVL树


    定义:每个节点的左右子树的高度最多差1的二叉查找树。(空树的高度为-1)。

    AVL树保证树的高度只比log(N)多一点,因此除了插入删除外,可以保证所有的树操作都以O(logN)执行。

    当插入一个节点的时候,只有那些从插入点到根节点路径上的点的平衡性可能被破坏,在最深的不满足平衡性的节点进行平衡操作,可以重新使整个树满足AVL特性。

    主要操作:对不满足AVL特性的子树执行单旋转和双旋转操作,使得插入后的子树保持和插入前的子树相同的高度。

    节点的基本定义:

     1 struct AvlNode;
     2 typedef struct AvlNode *Position;
     3 typedef struct AvlNode *AvlTree;
     4 
     5 struct AvlNode{
     6     ElementType Element;
     7     AvlTree Left;
     8     AvlTree Right;
     9     int Height;
    10 };

    单旋转(左-左  右-右)代码如下:

     1 Position SingleRotateWithLeft(AvlTree K2){
     2     Position K1;
     3     K1 = K2->Left;
     4     K2->Left = K1->Right;
     5     K1->Right = K2;
     6 
     7     K2->Height = max(Height(K2->Left), Height(K2->Right)) + 1;
     8     K1->Height = max(Height(K1->Left), K2->Height) + 1;
     9     return K1;
    10 }
    11 
    12 Position SingleRotateWithRight(AvlTree K2){
    13     Position K1;
    14     K1 = K2->Right;
    15     K2->Right = K1->Left;
    16     K1->Left = K2;
    17     
    18     K2->Height = max(Height(K2->Left), Height(K2->Right)) + 1;
    19     K1->Height = max(K2->Height, Height(K1->Right)) + 1;
    20     return K1;
    21 }

    双旋转(左-右 右-左)代码如下:

    1 Position DoubleRotateWithLeft(AvlTree K3){
    2     K3->Left = SingleRotateWithRight(K3->Left);
    3     return SingleRotateWithLeft(K3);
    4 }
    5 
    6 Position DoubleRotateWithRight(AvlTree K3){
    7     K3->Right = SingleRotateWithLeft(K3->Right);
    8     return SingleRotateWithRight(K3);
    9 }

    插入算法如下:

     1 AvlTree Insert(ElementType X, AvlTree T){
     2     if(T == NULL){
     3         T = (AvlTree)malloc(sizeof(struct AvlNode));
     4         T->Height = 0;
     5         T->Left = T->Right = NULL;
     6         T->Element = X;
     7     }
     8     else if(X < T->Element){
     9         T->Left = Insert(X, T->Left);
    10         if(Height(T->Left)-Height(T->Right) == 2){
    11             if(X < T->Left->Element){
    12                 T = SingleRotateWithLeft(T);
    13             }
    14             else{
    15                 T = DoubleRotateWithLeft(T);
    16             }
    17         }
    18     }
    19     else if(X > T->Element){
    20         T->Right = Insert(X, T->Right);
    21         if(Height(T->Right)-Height(T->Left) == 2){
    22             if(X > T->Right->Element){
    23                 T = SingleRotateWithRight(T);
    24             }
    25             else{
    26                 T = DoubleRotateWithRight(T);
    27             }
    28         }
    29     }
    30 
    31     T->Height = max(Height(T->Left), Height(T->Right)) + 1;
    32     return T;
    33 }
  • 相关阅读:
    CF500F New Year Shopping [线段树分治,背包]
    P5344 【XR-1】逛森林[倍增优化建图,zkw线段树优化spfa]
    CF452F Permutation [哈希,树状数组]
    [NOI Online #2 提高组]子序列问题
    牛客挑战赛39题解
    #6036. 「雅礼集训 2017 Day4」编码 [前缀优化2sat]
    CF1156E Special Segments of Permutation [分治,set]
    #6198. 谢特 [后缀自动机,01trie合并,启发式合并]
    P4246 [SHOI2008]堵塞的交通 [动态图连通性]
    CF1096G Lucky Tickets [NTT,多项式快速幂]
  • 原文地址:https://www.cnblogs.com/lwyeah/p/8810310.html
Copyright © 2020-2023  润新知