#include<stdio.h>
 #include<stdlib.h>

 typedef struct AvlNode *Position;
 typedef struct AvlNode *AvlTree;
 typedef int ElementType;

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

 //Avl函数的声明
 AvlTree CreateTree();                                //创建Avl树
 Position Find(ElementType Element, AvlTree T);       //查找
 Position FindMax(AvlTree T);
 Position FindMin(AvlTree T);
 AvlTree Insert(ElementType Element, AvlTree T);      //插入
 AvlTree Delete(ElementType Element, AvlTree T);      //删除 

 //插入结点到AVL树所需的函数声明
 int Height(AvlTree T);                                //返回树的高
 int Max(ElementType A, ElementType B);                //比较树高
 Position SingleRotateWithLeft(Position K2);           //左单旋
 Position SingleRotateWithRight(Position K2);          //右单旋
 Position DoubleRotateWithLeft(Position K3);           //左右双旋
 Position DoubleRotateWithRight(Position K3);          //右左双旋 

 void PreOrder_1(AvlTree T);                           //先序遍历(递归) 

 int main()
 {
     AvlTree T;
     ElementType Element;

     , i;

         printf("                   本程序实现Avl树的基本操作。                     \n");
         printf("|                                                                      |\n");
         printf("|**********************************************************************|\n");
         printf("|                        Avl树的基本操作如下:                         |\n");
         printf("|                           0.创建Avl树                                |\n");
         printf("|                           1.查找                                     |\n");
         printf("|                           2.插入                                     |\n");
         printf("|                           3.删除                                     |\n");
         printf("|                           4.将Avl树遍历                              |\n");
         printf("|**********************************************************************|\n"); 

     while(flag){

         printf("|                           请选择功能:                               |\n"); 

         scanf("%d", &i);
                               //输入需要选择的功能
         switch(i){
             :
                 printf("请输入Avl树的根结点(0代表NULL):");
                 T = CreateTree();
                 break; 

             :
                 if(T){
                     printf("请输入要查找的元素:");
                     scanf("%d", &Element);
                     if( Find(Element, T))
                         printf("该元素存在!\n");
                     else
                          printf("该元素不存在!\n");
                 }else
                     printf("       Avl树为空!\n");
                 break;     

             :
                 if(T){
                     printf("请输入要插入的元素:");
                     scanf("%d", &Element);
                     T = Insert(Element, T);
                 }else
                     printf("       Avl树为空!\n");
                 break;    

             :
                 if(T){
                     printf("请输入要删除的元素:");
                     scanf("%d", &Element);
                     T = Delete(Element, T);
                 }else
                     printf("       Avl树为空!\n");
                 break;
             :
                 if(T){
                     printf("(先序)遍历的结果为:");
                     PreOrder_1(T);
                     printf("\n");
                 }else
                     printf("       Avl树为空!\n");
                 break;    

             default:
                 flag = ;
                 printf("程序运行结束,按任意键退出!\n");
         }  

     }
     ;
 } 

 //Avl树的函数
 AvlTree CreateTree()                                  //创建Avl树
 {
     ElementType ch;
     AvlTree T; 

     scanf("\n%d", &ch);
     )
        T = NULL;
     else{
         if(!(T = (AvlTree)malloc(sizeof(AvlNode))))
            exit(-);
         T->Element  = ch;
         printf("%d的左儿子为:", T->Element );
         T->Left = CreateTree();
         printf("%d的右儿子为:", T->Element );
         T->Right = CreateTree();
     }
     return T;
 }

 Position Find(ElementType Element, AvlTree T)                //Avl树的查找
 {
     if(T == NULL)
         return NULL;
     if(Element < T->Element)         //向左找
         return Find(Element, T->Left);
     else if(Element > T->Element)    //向右找
         return Find(Element, T->Right);
     else
         return T;
 }

 Position FindMax(AvlTree T)                            //找最大值(非递归)
 {
     if(T != NULL){
         while(T->Right != NULL )    //一直向右找
             T = T->Right;
     }

      return T;
 }
 // Position FindMax(AvlTree T)                         //找最大值(递归)
 //{
 //    if(T == NULL)
 //      return NULL;
 //  else if(T->Right == NULL)
 //        return T;
 //    else
 //        return FindMax(T->Right);
 //    }

 Position FindMin(AvlTree T)                            //找最小值(非递归)
 {
     if(T != NULL){                 //一直向左找
         while(T->Left != NULL )
             T = T->Left;
     }

      return T;
 }
 // Position FindMin(AvlTree T)                         //找最小值(递归)
 //{
 //    if(T == NULL)
 //      return NULL;
 //  else if(T->Left == NULL)
 //        return T;
 //    else
 //        return FindMax(T->Left);
 //    }

 AvlTree Insert(ElementType Element, AvlTree T)         //插入元素到AVL树中
 {
     if(T == NULL){                    //如果是空树,则初始化之
         if(!(T = (AvlTree)malloc(sizeof(AvlNode))))
            exit(-);
         else{
             T->Element = Element;
             T->Height = ;
             T->Left = T->Right = NULL;
         }
     }else if(Element < T->Element ){  //向左找
         T->Left = Insert(Element, T->Left);
         )  //破坏了Avl树的平衡
             if(Element < T->Left->Element )
                 T = SingleRotateWithLeft(T); //左 单旋(可以理解为此时树向左下沉(即天平偏向左边,需要向右挪树))
             else
                 T = DoubleRotateWithLeft(T); //左右双旋     (先执行右单旋,再执行左单旋,一共旋转2次)
     }else if(Element > T->Element ){
         T->Right = Insert(Element, T->Right);
         )
             if(Element > T->Right->Element )
                 T = SingleRotateWithRight(T); //右单旋
             else
                 T = DoubleRotateWithRight(T); //右左双旋
     }

     T->Height = Max(Height(T->Left ), Height(T->Right )) + ;  //平衡后新树的高度
     return T;

 }
 AvlTree Delete(ElementType Element, AvlTree T)               //删除元素 (与搜索二叉树的删除类似)
 {
     Position TmpCell;
     if(T == NULL)                //空树
         printf("没找到该元素,无法删除!\n");
     else if(Element < T->Element)
         T->Left = Delete(Element, T->Left);
     else if(Element > T->Element)
         T->Right = Delete(Element, T->Right);
     else if(T->Left && T->Right){ //要删除的树左右都有儿子
         TmpCell = FindMin(T->Right);   //用该结点右儿子上最小结点替换该结点,然后与只有一个儿子的操作方法相同
         T->Element = TmpCell->Element;
         T->Right = Delete(T->Element, T->Right);
     }else{
         TmpCell = T;        //要删除的结点只有一个儿子
         if(T->Left == NULL)
             T = T->Right;
         else if(T->Right == NULL)
             T = T->Left;
         free(TmpCell);
     }
     return T;
 }   

 void PreOrder_1(AvlTree T)                           //先序遍历(递归)
 {
     if(T){

         printf("%d  ", T->Element);
         PreOrder_1(T->Left);
         PreOrder_1(T->Right);
     }
  } 

  int Height(AvlTree T)                               //返回的高
  {
      if(T == NULL)
          ;
      else
          + Max(Height(T->Left ), Height(T->Right ));
   } 

   int Max(ElementType A, ElementType B)                //比较树高
   {
       if(A > B)
           return A;
       else
         return B;
    } 

 Position SingleRotateWithLeft(Position K2)           //左单旋
 {
     Position K1;

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

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

     return K1;

  } 

 Position SingleRotateWithRight(Position K2)          //右单旋
 {
     Position K1;

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

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

     return K1;
  } 

 Position DoubleRotateWithLeft(Position K3)          //左右双旋
 {
     K3->Left = SingleRotateWithRight(K3->Left );

     return SingleRotateWithLeft(K3);

  } 

 Position DoubleRotateWithRight(Position K3)         //右左双旋
 {
     K3->Right = SingleRotateWithLeft(K3->Right );

     return SingleRotateWithRight(K3);
  } 

Avl树的基本操作(c语言实现)的更多相关文章

  1. AVL树的创建--C语言实现

    AVL树是一种自平衡(Self-balancing)二叉查找树(Binary Search Tree),要求任何一个节点的左子树和右子树的高度之差不能超过1. AVL树的插入操作首先会按照普通二叉查找 ...

  2. AVL树(三)之 Java的实现

    概要 前面分别介绍了AVL树"C语言版本"和"C++版本",本章介绍AVL树的Java实现版本,它的算法与C语言和C++版本一样.内容包括:1. AVL树的介绍 ...

  3. AVL树(二)之 C++的实现

    概要 上一章通过C语言实现了AVL树,本章将介绍AVL树的C++版本,算法与C语言版本的一样. 目录 1. AVL树的介绍2. AVL树的C++实现3. AVL树的C++测试程序 转载请注明出处:ht ...

  4. AVL树的左旋右旋理解 (转)

    AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多 ...

  5. 图解数据结构树之AVL树

    AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...

  6. AVL树之 Java的实现

    AVL树的介绍 AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1:而右边的不 ...

  7. AVL树的理解及自写AVL树

    AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多 ...

  8. AVL树的实现——c++

    一.概念 AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的.它是最先发明的自平衡二叉查找树,也被称为高度平衡树.相比于"二叉查找树",它 ...

  9. linux 内核数据结构之 avl树.

    转载: http://blog.csdn.net/programmingring/article/details/37969745 https://zh.wikipedia.org/wiki/AVL% ...

随机推荐

  1. 黄聪:get_posts 函数 | wordpress

    get_posts 函数,简单的来讲是 get_post 的复数新形势,但因为是文章多篇提取,所以使用方法上却略有不同,支持众多参数选择需要提取的文章,在 CMS 主题中经常被用到,当然如果你对 Wo ...

  2. 黄聪:C#中WebClient自动判断编码是UTF-8还是GBK,并且有超时判断功能

    public class WebDownload : WebClient { private int _timeout; /// <summary> /// 超时时间(毫秒) /// &l ...

  3. Python 结巴分词(1)分词

    利用结巴分词来进行词频的统计,并输出到文件中. 结巴分词github地址:结巴分词 结巴分词的特点: 支持三种分词模式: 精确模式,试图将句子最精确地切开,适合文本分析: 全模式,把句子中所有的可以成 ...

  4. 安装完CentOS 7 后必做的七件事[转]

    CentOS是最多人用来运行服务器的 Linux 版本,最新版本是 CentOS 7.当你兴趣勃勃地在一台主机或 VPS 上安装 CentOS 7 后,首要的工作肯定是加强它的安全性,以下列出的七件事 ...

  5. cvc-elt.1: 找不到元素 'beans' 的声明

    这次遇到的这个错误又坑爹又低级 , 是因为网上抄到了错误的xsd搞的. 这是网上抄到的 xsi:schemalocation=" http://www.springframework.org ...

  6. jQuery实现的鼠标滑过切换图片代码实例

    jQuery实现的鼠标滑过切换图片代码实例:有时候网页需要这样的简单效果,那就是当鼠标滑过默认图片的时候,能够实现图片的切换,可能在实际应用中,往往没有这么简单,不过大家可以自行扩展一下,下面简单介绍 ...

  7. SQL查询结果增加序号列

    --sql 2000 ) ,学号 ,姓名 from tb t --sql 2005 select 序号 = row_number() over(order by 学号),学号 ,姓名 from tb ...

  8. 如何使weblogic11g类似weblogic923一样统一使用一个boot.properties文件

    如何使weblogic11g类似weblogic923一样 统一使用一个boot.properties文件 1.在weblogic域下创建文件boot.properties输入用户密码例如:usern ...

  9. java中的static变量

    java中的static变量 例如 public static int num=0: num+=1;放在函数里面 调用一次变动一次.

  10. 菜鸟-手把手教你把Acegi应用到实际项目中(1.2)

    7) daoAuthenticationProvider 进行简单的基于数据库的身份验证.DaoAuthenticationProvider获取数据库中的账号密码并进行匹配,若成功则在通过用户身份的同 ...