• [数据结构与算法] : AVL树


    头文件

     1 typedef int ElementType;
     2 
     3 #ifndef _AVLTREE_H_
     4 #define _AVLTREE_H_
     5 
     6 struct AvlNode;
     7 typedef struct AvlNode *Position;
     8 typedef struct AvlNode *AvlTree;
     9 
    10 AvlTree MakeEmpty(AvlTree T);
    11 Position Find(ElementType X, AvlTree T);
    12 Position FindMin(AvlTree T);
    13 Position FindMax(AvlTree T);
    14 AvlTree Insert(ElementType X, AvlTree T);
    15 AvlTree Delete(ElementType X, AvlTree T);
    16 ElementType Retrieve(Position P);
    17 void PrintTree(AvlTree T);
    18 
    19 #endif

    源文件

      1 #include "fatal.h"
      2 #include "avltree.h"
      3 #include <malloc.h>
      4 
      5 struct AvlNode
      6 {
      7     ElementType Element;
      8     AvlTree Left;
      9     AvlTree Right;
     10     int     Height;
     11 };
     12 
     13 AvlTree MakeEmpty(AvlTree T) // 同二叉查找树
     14 {
     15     if(T != NULL) // 递归终止
     16     {
     17         MakeEmpty(T->Left);
     18         MakeEmpty(T->Right);
     19         free(T);
     20     }
     21     return T;
     22 }
     23 
     24 Position Find(ElementType X, AvlTree T) // 同二叉查找树
     25 {
     26     if(T == NULL)
     27         return NULL;
     28     else if(X < T->Element)
     29     {
     30         return Find(X, T->Left);
     31     }
     32     else if(X > T->Element)
     33     {
     34         return Find(X, T->Right);
     35     }
     36     else
     37         return T;
     38 }
     39 
     40 Position FindMin(AvlTree T) // 递归实现
     41 {
     42     if(T == NULL)
     43         return NULL;
     44     else if(T->Left == NULL)
     45         return T;
     46     else
     47         return FindMin(T->Left);
     48 }
     49 
     50 Position FindMax(AvlTree T) // 非递归实现
     51 {
     52     if(T != NULL)
     53         while(T->Right != NULL)
     54             T = T->Right;
     55 
     56     return T;
     57 }
     58 
     59 static int Height(Position P)
     60 {
     61     if(P == NULL)
     62         return -1; // 空树高度为-1
     63     else
     64         return P->Height;
     65 }
     66 
     67 static int Max(int Left, int Right)
     68 {
     69     return Left > Right ? Left : Right;
     70 }
     71 
     72 /* This function can be called only if K2 has a left child */
     73 /* Perform a rotate between a node (K2) and its left child */
     74 /* Update heights, then return new root */
     75 static Position SingleRotateWithLeft(Position K2)
     76 {
     77     Position K1;
     78 
     79     K1 = K2->Left;
     80     K2->Left = K1->Right;
     81     K1->Right = K2;
     82 
     83     K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
     84     K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
     85 
     86     return K1;  /* New root */
     87 }
     88 
     89 /* This function can be called only if K1 has a right child */
     90 /* Perform a rotate between a node (K1) and its right child */
     91 /* Update heights, then return new root */
     92 static Position SingleRotateWithRight(Position K1)
     93 {
     94     Position K2;
     95 
     96     K2 = K1->Right;
     97     K1->Right = K2->Left;
     98     K2->Left = K1;
     99 
    100     K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
    101     K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    102 
    103     return K2;  /* New root */
    104 }
    105 
    106 /* This function can be called only if K3 has a left */
    107 /* child and K3's left child has a right child */
    108 /* Do the left-right double rotation */
    109 /* Update heights, then return new root */
    110 static Position DoubleRotateWithLeft(Position K3)
    111 {
    112     /* Rotate between K1 and K2 */
    113     K3->Left = SingleRotateWithRight(K3->Left);
    114     /* Rotate between K3 and K2 */
    115     return SingleRotateWithLeft(K3);
    116 }
    117 
    118 /* This function can be called only if K1 has a right */
    119 /* child and K1's right child has a left child */
    120 /* Do the right-left double rotation */
    121 /* Update heights, then return new root */
    122 static Position DoubleRotateWithRight(Position K1)
    123 {
    124     /* Rotate between K3 and K2 */
    125     K1->Right = SingleRotateWithLeft(K1->Right);
    126     /* Rotate between K1 and K2 */
    127     return SingleRotateWithRight(K1);
    128 }
    129 
    130 // 1. 找位置; 2. 插入; 3. 平衡性; 4. 旋转
    131 AvlTree Insert(ElementType X, AvlTree T)
    132 {
    133     if(T == NULL)
    134     {
    135         /* Create and return a one-node tree */
    136         T = (AvlTree)malloc(sizeof(struct AvlNode));
    137         if(T == NULL)
    138             FatalError("Out of space!");
    139         else
    140         {
    141             T->Left = T->Right = NULL;
    142             T->Height = 0;
    143             T->Element = X;
    144         }
    145     }
    146     else if(X < T->Element)
    147     {
    148         T->Left = Insert(X, T->Left);
    149         // 因为插到左边了, 所以肯定是左边比较高
    150         if(Height(T->Left) - Height(T->Right) == 2)
    151         {
    152             if(X < T->Left->Element)
    153                 T = SingleRotateWithLeft(T);
    154             else
    155                 T = DoubleRotateWithLeft(T);
    156         }
    157     }
    158     else if(X > T->Element)
    159     {
    160         T->Right = Insert(X, T->Right);
    161         // 插到右边了, 右边比较高
    162         if(Height(T->Right) - Height(T->Left) == 2)
    163         {
    164             if(X > T->Right->Element)
    165                 T = SingleRotateWithRight(T);
    166             else
    167                 T = DoubleRotateWithRight(T);
    168         }
    169     }
    170     /* Else X is in the tree already; we'll do nothing */
    171     T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    172 
    173     return T;
    174 }
    175 
    176 AvlTree Delete(ElementType X, AvlTree T)
    177 {
    178     printf( "Sorry; Delete is unimplemented; %d remains
    ", X );
    179     return T;
    180 }
    181 
    182 ElementType Retrieve(Position P)
    183 {
    184     return P->Element;
    185 }
    186 
    187 void PrintTree(AvlTree T)
    188 {
    189     if( T != NULL)
    190     {
    191         PrintTree(T->Left);
    192         printf("%d ", T->Element);
    193         PrintTree(T->Right);
    194     }
    195 }

    测试文件

     1 #include "avltree.h"
     2 #include <stdio.h>
     3 
     4 main( )
     5 {
     6     AvlTree T;
     7     Position P;
     8     int i;
     9     int j = 0;
    10 
    11     T = MakeEmpty( NULL );
    12     for( i = 0; i < 50; i++, j = ( j + 7 ) % 50 )
    13         T = Insert( j, T );
    14     for( i = 0; i < 50; i++ )
    15         if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
    16             printf( "Error at %d
    ", i );
    17 
    18  /* for( i = 0; i < 50; i += 2 )
    19         T = Delete( i, T );
    20 
    21     for( i = 1; i < 50; i += 2 )
    22         if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
    23             printf( "Error at %d
    ", i );
    24     for( i = 0; i < 50; i += 2 )
    25         if( ( P = Find( i, T ) ) != NULL )
    26             printf( "Error at %d
    ", i );
    27 */
    28     printf( "Min is %d, Max is %d
    ", Retrieve( FindMin( T ) ),
    29                Retrieve( FindMax( T ) ) );
    30     PrintTree(T);
    31     return 0;
    32 }
  • 相关阅读:
    获取本机IP,用户代理
    10 种机器学习算法的要点(附 Python)(转载)
    怎么查找执行比较慢的sql语句-DBA给的建议
    .net 调度器怎么实现心跳(socket除了他,没选择吧)
    分布式多计算机调度平台
    续【C# 以管理员方式启动Winform,进而使用管理员控制Windows Service】
    C# 以管理员方式启动Winform,进而使用管理员控制Windows Service
    SqlServer2008根据现有表,获取该表的分区创建脚本
    SqlServer常用命令
    创建分区表过程
  • 原文地址:https://www.cnblogs.com/moon1992/p/7500076.html
Copyright © 2020-2023  润新知