zoukankan      html  css  js  c++  java
  • 二叉平衡查找树AvlTree(C实现)

    二叉平衡查找树即是一棵树中所有节点的左右子树高度差不超过1的查找树
    头文件——————————————————————————————
    #ifndef _AVLTREE_H_
    #define _AVLTREE_H_
    #include <stdlib.h>
    #include <iomanip>
    #include <iostream>
     
    typedef struct AvlNode *Position;
    typedef Position AvlTree;
    #define Element int
    struct AvlNode
    {
         Element data;
         int height;//叶子节点高度定义为0,其父节点为1以此类推
         AvlTree left;
         AvlTree right;
    };
     
    static int Height(AvlTree avl);
    void SwapAvlNode(Position *p1, Position *p2);
    Position GetNotBalancedNode(AvlTree avl);
    void MakeEmpty(AvlTree* pavl);
    Position Find(Element x, AvlTree avl);
    Position FindMin(AvlTree avl);
    Position FindMax(AvlTree avl);
    void Insert(Element x, AvlTree* pavl);
    void Delete(Element x, AvlTree* pavl);
    Element Retrieve(Position p);
    void SingleRotateWithLeftLeft(Position *pK2);
    void SingleRotateWithRightRight(Position *pK2);
    void DoubleRotateWithLeftRight(Position *pK3);
    void DoubleRotateWithRightLeft(Position *pK3);
    void PrintTree(AvlTree avl, int Depth, int ctrl);
    #endif
    源文件————————————————————————————————
    #include "./AvlTree.h"
     
    int Max(int a, int b)
    {
         if(a <= b)
              return b;
         return a;
    }
    void SwapAvlNode(Position *p1, Position *p2)
    {
         Position tmp = *p1;
         *p1 = *p2;
         *p2 = tmp;
    }
    int Abs(int a)
    {
         if(a < 0) return -a;
         return a;
    }
    static int Height(AvlTree avl)
    {
         if(NULL == avl)
              return -1;
         else
              return avl->height;
    }
    Position GetNotBalancedNode(AvlTree avl)
    {
         if(NULL == avl)
              return NULL;
         else
         {
              if(Height(avl->left) - Height(avl->right) == Abs(2))//not balanced
                   return avl;
              else
              {
                   Position res = GetNotBalancedNode(avl->left);
                   if(NULL != res)//avl->left is not balanced
                        return res;
                   else
                        return GetNotBalancedNode(avl->right);
              }
         }
    }
    void MakeEmpty(AvlTree* pavl)
    {
         if(NULL != (*pavl))
         {
              MakeEmpty(&((*pavl)->left));
              MakeEmpty(&((*pavl)->right));
              free(*pavl);
              *pavl = NULL;
         }
    }
    Position Find(Element x, AvlTree avl)
    {
         Position pos = avl;
         while(NULL != pos)
         {
              if(x < Retrieve(pos))
                   pos = pos->left;
              else if(x > Retrieve(pos))
                   pos = pos->right;
              else
                   break;
         }
         return pos;
    }
    Position FindMin(AvlTree avl)
    {
         while(NULL != avl && NULL != avl->left)
              avl = avl->left;
         return avl;
    }
    Position FindMax(AvlTree avl)
    {
         while(NULL != avl && NULL != avl->right)
              avl = avl->right;
         return avl;
    }
    void Insert(Element x, AvlTree* pavl)
    {
         if(NULL == (*pavl))
         {
              Position tmp = (Position)malloc(sizeof(struct AvlNode));
              if(NULL == tmp)
                   return ;
              tmp->data = x;
              tmp->height = 0;
              tmp->left = tmp->right = NULL;
              *pavl = tmp;
         }
         else
         {
              if(x < Retrieve(*pavl))//在*pavl的左儿子上插入
              {
                   Insert(x, &((*pavl)->left));
                   if(Height((*pavl)->left) - Height((*pavl)->right) == 2)//不平衡
                   {
                        if(x < Retrieve((*pavl)->left))//左儿子的左子树
                             SingleRotateWithLeftLeft(pavl);
                        else//左儿子的右子树
                             DoubleRotateWithLeftRight(pavl);
                   }
              }
              else if(x > Retrieve(*pavl))//在*pavl的右儿子上插入
              {
                   Insert(x, &((*pavl)->right));
                   if(Height((*pavl)->right) - Height((*pavl)->left) == 2)//不平衡
                   {
                        if(x > Retrieve((*pavl)->right))//右儿子的右子树
                             SingleRotateWithRightRight(pavl);
                        else//右儿子的左子树
                             DoubleRotateWithRightLeft(pavl);
                   }
              }
         }
         (*pavl)->height = Max(Height((*pavl)->left), Height((*pavl)->right)) + 1;
    }
    void Delete(Element x, AvlTree* pavl)
    {
         if(NULL == *pavl)
              return ;
         if(x < Retrieve((*pavl)))//go left
              Delete(x, &((*pavl)->left));
         else if(x > Retrieve((*pavl)))//go right
              Delete(x, &((*pavl)->right));
         else if(NULL != (*pavl)->left && NULL != (*pavl)->right)//*pavl has two children
         {
              //利用右子树的最小值tmp->data来替代被删除的节点上的值x,然后在右子树上递归的删除值tmp->data
              Position tmp = FindMin((*pavl)->right);
              (*pavl)->data = tmp->data;
              Delete(tmp->data, &((*pavl)->right));
         }
         else//*pavl has none or one child
         {
              Position tmp = *pavl;
              if(NULL == (*pavl)->left)//*pavl has right child
                   *pavl = (*pavl)->right;
              else if(NULL == (*pavl)->right)//*pavl has left child
                   *pavl = (*pavl)->left;
              free(tmp);
         }
         if(NULL != *pavl)//最后更新*pavl节点上的高度
         {
              (*pavl)->height = Max(Height((*pavl)->left), Height((*pavl)->right)) + 1;
              if(2 == Height((*pavl)->left) - Height((*pavl)->right))//not balanced
              {
                   if(NULL == (*pavl)->left->right)
                        SingleRotateWithLeftLeft(pavl);
                   else
                        DoubleRotateWithLeftRight(pavl);
              }
              else if(2 == Height((*pavl)->right) - Height((*pavl)->left))//not balance
              {
                   if(NULL == (*pavl)->right->left)
                        SingleRotateWithRightRight(pavl);
                   else
                        DoubleRotateWithRightLeft(pavl);
              }
         }
    }
    Element Retrieve(Position p)
    {
         return p->data;
    }
    void SingleRotateWithLeftLeft(Position *pK2)
    {
         Position k2 = *pK2;
         Position k1 = k2->left;
         k2->left = k1->right;
         k1->right = k2;
         k1->height = Max(Height(k1->left), Height(k2)) + 1;
         k2->height = Max(Height(k2->left), Height(k2->right)) + 1;
         *pK2 = k1;
    }
    void SingleRotateWithRightRight(Position *pK2)
    {
         Position k2 = *pK2;
         Position k1 = k2->right;
         k2->right = k1->left;
         k1->left = k2;
         k1->height = Max(Height(k2), Height(k1->right)) + 1;
         k2->height = Max(Height(k2->left), Height(k2->right)) + 1;
         *pK2 = k1;
    }
    void DoubleRotateWithLeftRight(Position *pK3)
    {
         SingleRotateWithRightRight(&((*pK3)->left));
         SingleRotateWithLeftLeft(pK3);
    }
    void DoubleRotateWithRightLeft(Position *pK3)
    {
         SingleRotateWithLeftLeft(&((*pK3)->right));
         SingleRotateWithRightRight(pK3);
    }
    void PrintTree(AvlTree avl, int Depth, int ctrl)//ctrl:0=root 1=left 2=right
    {
         
         if(NULL != avl)
         {
              std::cout<<std::setw(Depth);
              if(0 == ctrl)
                   std::cout<<"rt:";
              else if(1 == ctrl)
                   std::cout<<"l";
              else if(2 == ctrl)
                   std::cout<<"r";
              std::cout<<avl->data<<std::endl;
              PrintTree(avl->left, Depth+3, 1);
              PrintTree(avl->right, Depth+3, 2);
         }
    }
     
     
     
     
  • 相关阅读:
    深入理解DB2缓冲池(BufferPool)
    收银台采坑总结
    webpack4的总结
    无心法师-讲解
    cache 缓存的处理
    用es6方式的写的订阅发布的模式
    Skeleton Screen -- 骨架屏--应用
    promise实现原理
    业务线移动端适配方案总结
    vdom,diff,key 算法的了解
  • 原文地址:https://www.cnblogs.com/hailong88/p/3236570.html
Copyright © 2011-2022 走看看