AVL平衡樹c語言實現與測試-建立自己的c資料結構與演算法庫系列(最新修改)(13)

來源:互聯網
上載者:User
重新修改讓我非常鬱悶,本來已經詳細分析,圖文並茅,自認為分析得非常晰。
寫完儲存,居然沒有成功,一大堆工作白費了。CSDN這個部落格真是讓我失望啊,Best4c中畫圖非常辛苦,可是畫完了也白費了。
唉呀,現在就先把實現的原始碼放這裡吧,如果有讀者要求我重新寫演算法分析並加片,我也會接著做。
   既然如此了,說是修改那就簡單提幾點吧,AVL平衡樹的實現是在二叉尋找樹的基礎上實現的,和二叉尋找樹的區別只在於插入和刪除這兩個操作。
插入和刪除都是遞迴的,
1。對於每次遞迴插入,都需要判斷當前節點的左右子樹是否平衡,如果不平衡則進行旋轉調整,旋轉分為左單旋轉,左雙旋轉,右單旋轉,和右雙旋轉.對於四種調整,均由一個單獨的函數實現。
2。對於每次刪除,如果被刪除的節點左右孩子有空的:
         如果左孩子為空白則用右孩子接上,否則用左孩子接上。
  如果左右孩子都不為空白,則
       當前要刪除的節點和其右子樹的最小節點交換值,然後遞迴的刪除右子樹的最小節點,對於刪除路線中的每一個節點都要進行平衡調整(假如必要的話),此調整和1中的類似,只是我把它放在了一個單獨的函數AVL_Rebanlence(t)裡了。
 
可見,本AVL樹的設計實現是相當優雅的,各功能都分模組實現了。

/***AVL樹的實現分為兩個檔案AVLTree.h與AVLTree.c****/
/**AVLTree.h**/
 /**********************************
*author:Felix
*last update:Sat Jan 12 06:12:15 EST 2008
*Address me and exchange our idea ^_^,QQ:349871604,e-mail:lzqziliao2004@163.com
*description:
*
*
*
*/
#ifndef ___AVLTREE___
#define ___AVLTREE___
#include<stdio.h>
#include<stdlib.h>
  typedef int AVL_Element;
extern struct AVL_TreeNode;
typedef struct AVL_TreeNode *AVL_Tree;
typedef struct AVL_TreeNode *AVL_Position;

AVL_Tree AVL_MakeEmpty(AVL_Tree t);
AVL_Position AVL_Find(AVL_Element e,AVL_Tree t);
AVL_Position AVL_FindMin(AVL_Tree t);
AVL_Position AVL_FindMax(AVL_Tree t);
AVL_Tree AVL_Delete(AVL_Element e ,AVL_Tree t);
AVL_Tree AVL_Insert(AVL_Element e ,AVL_Tree t);
AVL_Element AVL_Retrieve(AVL_Position p);

#endif

/**AVLTree.c**/
/**********************************
*author:Felix
*last update:Sat Jan 12 06:12:15 EST 2008
*Address me and exchange our idea ^_^,QQ:349871604,e-mail:lzqziliao2004@163.com
*description:
*
*
*
*/
#include "AVLTree.h"
#define MAX(a,b) ((a>b)?a:b)
struct AVL_TreeNode
{
  int height;
  AVL_Element e;
  AVL_Tree left;
  AVL_Tree right;
};
static int Height(AVL_Position p)
{
  if(p)return p->height;
   return -1;
}
/*rotate function*/
AVL_Position AVL_SingleRotateLeft(AVL_Position p)
{
   AVL_Position tmp;
   tmp=p->left;
   p->left=tmp->right;
   tmp->right=p;
   p->height=MAX(Height(p->left),Height(p->right))+1;
   tmp->height=MAX(Height(tmp->left),p->height);
   return tmp;
  
}
AVL_Position AVL_SingleRotateRight(AVL_Position p)
{
    AVL_Position tmp;
    tmp=p->right;
    p->right=tmp->left;
    tmp->left=p;
    p->height=MAX(Height(p->left),Height(p->right))+1;
    tmp->height=MAX(p->height,Height(tmp->right));
    return tmp;
}
AVL_Position AVL_DoubleRotateRight(AVL_Position p)
{
   p->right=AVL_SingleRotateLeft(p->right);
   return AVL_SingleRotateRight(p);
}
AVL_Position AVL_DoubleRotateLeft(AVL_Position p)
{
   p->left=AVL_SingleRotateRight(p->left);
  return AVL_SingleRotateLeft(p);
}

AVL_Tree AVL_MakeEmpty(AVL_Tree t)
{
  if(t)
  {
     AVL_MakeEmpty(t->left);
     AVL_MakeEmpty(t->right);
     free(t);
  }
  return NULL;
}
AVL_Position AVL_Find(AVL_Element e,AVL_Tree t)
{
 
  if(t)
  {
    if(e>t->e)return AVL_Find(e,t->right);
    else if(e<t->e)return AVL_Find(e,t->left);
    else return (AVL_Position)t;
  }
  else return NULL;
}

/*find the minimum element*/
AVL_Position AVL_FindMin(AVL_Tree t)
{
   if(t)
    while(t->left)t=t->left;
    return (AVL_Position)t;
}
/*find the maximum element*/
AVL_Position AVL_FindMax(AVL_Tree t)
{
   if(t)
    while(t->right)t=t->right;
    return (AVL_Position)t;
}

static AVL_Tree AVL_Rebalance(AVL_Position p)
{
  if(Height(p->left)-Height(p->right)==2)
  {
      if(Height(p->left->left)>Height(p->left->right))/*LL**/
       {
           return AVL_SingleRotateLeft(p);
       }
       else/*LR*/
       {
          return AVL_DoubleRotateLeft(p);
       }
  }
  else
  if(Height(p->left)-Height(p->right)==-2)
  {
 
      if(Height(p->right->right)>Height(p->right->left))/*RR**/
      {
         return AVL_SingleRotateRight(p);
      }/*RL*/
    else
      {
         return AVL_DoubleRotateRight(p);
      }
  }
}
static AVL_Tree AVL_DeleteMin(AVL_Tree t)
{
  if(t->left){
       t=AVL_DeleteMin(t->left);
       return AVL_Rebalance(t);
   }
  else
  {
     free(t);
     return NULL;
  }
}
AVL_Tree AVL_Delete(AVL_Element e ,AVL_Tree t)
{
   AVL_Position p;
   if(t)
   {
     if(e>t->e)t->right=AVL_Delete(e,t->right);
     else if(e<t->e) t->left=AVL_Delete(e,t->left);
    /*find it*/
     else if(t->left&&t->right)
      {
         p=AVL_FindMin(t->right);
         t->e=p->e;
         t->right=AVL_DeleteMin(t->right);
      }
     else
     {
       p=t;
       if(t->left==NULL)t=t->right;
       else t=t->left;
       free(p);
     }
   }
  return AVL_Rebalance(t);
}

AVL_Tree AVL_Insert(AVL_Element e ,AVL_Tree t)
{
   
   if(t==NULL)/*insert as leaf child*/
   {
       t=(AVL_Tree)malloc(sizeof(struct AVL_TreeNode));
       t->e=e;
       t->left=t->right=NULL;
       t->height=0;
   }
   else
   if(e>t->e)
    {
         t->right=AVL_Insert(e,t->right);
         if(Height(t->right)-Height(t->left)==2)
          if(e>t->right->e)t=AVL_SingleRotateRight(t);
          else t=AVL_DoubleRotateRight(t);
    }else
   if(e<t->e)
    {
         t->left=AVL_Insert(e,t->left);
         if(Height(t->left)-Height(t->right)==2)
          if(e<t->left->e)t=AVL_SingleRotateLeft(t);
          else t=AVL_DoubleRotateLeft(t);
    }
  t->height=MAX(Height(t->left),Height(t->right))+1;
   return t;
}

AVL_Element AVL_Retrieve(AVL_Position p)
{
    return p->e;
}

/**測試檔案包括testAVL.c menu_c.h menu_c.c以及前面檔案(11)(文章為(12))所實現drawBitTree.h/drawBitTree.c**/

/**testAVL.c**/
/*vgalib庫可能不太穩定。
*author:Felix
*create date:Tue Jan 15 20:14:10 EST 2008
*last update:Tue Jan 15 20:14:10 EST 2008
*description:
*
*/
#include "menu_c.h"
#include<stdio.h>
#include<stdlib.h>
#include"AVLTree.h"
#include"drawBitTree.h"
struct AVL_TreeNode
{
  int height;
  AVL_Element e;
  AVL_Tree left;
  AVL_Tree right;
};
/******define some function to show the tree*******/
 int getkey(void * t)
{
   return ((AVL_Tree)t)->e;
}
void * getchild(void * t,int mode)
{
  if(mode==DB_LEFTCHILD)return ((AVL_Tree)t)->left;
  else return ((AVL_Tree)t)->right;
}
/*****************/
int main()
{
int n;
AVL_Tree t;
AVL_Position p;
t=AVL_MakeEmpty(NULL);

while(SELECT())
{
 switch (SELECTION)
 {
 case '1':
  printf("integer:>");
  scanf("%d",&n);
  t=AVL_Insert(n,t);

 break;
 case '2':
  printf("integer to delete:>");
  scanf("%d",&n);
  if(!AVL_Find(n,t))printf("sorry,no integer match");
  else {
   t=AVL_Delete(n,t);
   printf("deletion done");
  }
 break;
 case '3':
  while(p=AVL_FindMin(t))
  {
     printf("%d " ,AVL_Retrieve(p),t);
   t= AVL_Delete(AVL_Retrieve(p),t);
  }
 break;
 case '4':
  while(p=AVL_FindMax(t))
  {
     printf("%d " ,AVL_Retrieve(p));
    t=AVL_Delete(AVL_Retrieve(p),t);
  }
 break;
 case '5':
  if(!(p=AVL_FindMax(t)))printf("sorry,the tree is NULL");
else
  printf("%d",AVL_Retrieve(p));
 break;
 case '6':
  if(!(p=AVL_FindMin(t)))printf("sorry ,the tree is NULL");
  else
  printf("%d",AVL_Retrieve(p));
 break;
 case '7':
  
   DB_DrawBitTree(t,getchild,getkey);
 break;
 case '9':
 system("less ../AVL_tree.h");
 break;
 default:break;
 }
}
return 0;
}
/**menu_c.h**/
/*///////////////////////
*author:Felix
*create date:Fri Jan 11 03:45:18 EST 2008
*last update:Fri Jan 11 03:45:18 EST 2008
*description:
*
*
*/////////////////////
#include <stdio.h>
#ifndef __MENU____
#define __MENU____
#define SELECT() ((___sel=___select())!='0')
#define SELECTION ___sel
char ___sel;
char ___select();
/*
 define the menu:
*/
#endif

/**menu_c.c**/
/*///////////////////////
*author:Felix
*create date:Fri Jan 11 03:45:18 EST 2008
*last update:Fri Jan 11 03:45:18 EST 2008
*description:
*
*
*/////////////////////
#include "menu_c.h"
char *___menu[]={
 
"1.Insert a integer.",
"2.Delete an integer from the tree.",
"3.Sort and show from small to big(will delete the tree)",
"4.Sort and show from big to small(will delete the tree)",
"5.show the max",
"6.show the min", "9.Print the file ST_tree.h",
"7.show the tree",
"0.EXIT",
NULL
};
void ___showMenu()
{
 printf("please select:/n");
 char **p=___menu;
 while(*p)printf("%s/n",*p++);
 printf(":>");
}
char ___select()
{
char c;
 ___showMenu();
 while((c=getchar())=='/n');
 return c;
}

/**drawBitTree.h與drawBitTree.c的實現:***/
http://blog.csdn.net/liuzongqiang/archive/2008/01/16/2046194.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.