青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

AVL樹的簡單實現

#include <math.h>
#include <vector>
using namespace std;
#define max(a,b)  ((a)>(b)?(a):(b))
template<typename E>
class AVL_TMP

 template <typename E>
 class AVL_NODE
 {
 public:
  AVL_NODE():ln(0),rn(0),depth(0){}
  AVL_NODE( const E& e):data(e),ln(0),rn(0),depth(0){}
  ~AVL_NODE(){ if (ln) delete ln; if (rn) delete rn; }

  bool operator < (E& e){  return data < e; }
  bool operator > (E& e){  return data > e; }
  bool operator == (E& e){ return data == e; }
  bool operator != (E& e){ return data != e; }

  E getdata(){return data;}
  
  E data;
  int depth;
  AVL_NODE<E> *ln,*rn;
 };
 
public: 
 typedef E dataType;
 typedef AVL_TMP<E> Myt;
 typedef AVL_NODE<E> n;
 typedef n* npos;
 typedef npos iterator;
 enum unbalanceType {LL,RR,LR,RL};
 AVL_TMP():root(0),size(0),depth(-1){}
 ~AVL_TMP(){ if(root) delete root; }

 iterator begin(){return root;}
 bool insert(const E& e);
 npos find(const E& e);
 npos findpre(const E& e);
 bool del(dataType);
 bool balance(AVL_TMP<E>::iterator pos){
  if(pos == NULL) throw 0;
  int lh,rh;
  if(pos->ln == NULL ) lh = -1;
  else lh = pos->ln->depth;
  if(pos->rn == NULL ) rh = -1;
  else rh = pos->rn->depth;
  return abs( lh - rh ) < 2 ;
 }
 virtual void frontOrder(){};
 virtual void midOrder(){ };

protected:
 void LLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
 void LRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
 void RRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
 void RLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos);
 void updateDepth(AVL_TMP<E>::iterator pos);
 bool delAux(E const& e,AVL_TMP<E>::iterator pos = NULL);
 iterator findMax(iterator );
 iterator findMin(iterator );
 bool upTree(int iDepth,iterator itRoot,unsigned long iSize){depth = iDepth;root = itRoot;size = iSize; return true;}
 bool upRoutineDepth(vector<iterator>&);
 bool adjust(iterator a,iterator b,iterator c,iterator prePos = NULL);
 npos root;
 int depth;
 unsigned long size;
};
template<typename E>
bool AVL_TMP<E>::adjust(iterator a,iterator b,iterator c,iterator prePos){
 bool b1,b2;
 b1 = b == a->ln;
 b2 = c == b->ln;
 unbalanceType ub;
 if(b1&&!b2)   ub = LR;
 if(!b1&&b2)   ub = RL;
 if(b1&&b2)    ub = LL;
 if(!b1&&!b2)  ub = RR;
 switch(ub) {
  case  LL :LLr(a,prePos);
   break;
  case  LR :LRr(a, prePos);
   break;
  case  RR :RRr(a,prePos);
   break;
  case  RL :RLr(a,prePos);
   break;
 }  //end switch
 return true;
}
template<typename E>
bool AVL_TMP<E>::upRoutineDepth(vector<iterator>&routine){
 //該函數主要是將路徑節點的深度更新并且使得那些不平衡的節點平衡
 int size = routine.size();
 while (size--) {
  updateDepth(routine[size]);
  if (!balance(routine[size])) {//不平衡得調整
   iterator cur = routine[size],prePos = NULL;
   if(size-1>=0)
    prePos = routine[size-1];
   //檢查當前不平衡節點的哪顆子樹的高度更高
   bool bl = cur->ln != NULL;
   bool br = cur->rn != NULL;
   if (!bl) {//肯定有右孩子
    if(cur->rn->ln) RLr(cur,prePos);
    else RRr(cur,prePos);
   }
   else{//有左孩子
    if (!br) {//沒右孩子
     if (cur->ln->ln) LLr(cur,prePos);
     else LRr(cur,prePos);
    }
    else{ //有右孩子,此時需要檢查左右孩子的高度,則右子樹高度至少為1
     //因此左子樹高度至少為3,則左子樹的節點個數肯定大于4
     if (cur->ln->depth > cur->rn->depth) LLr(cur,prePos);
     else RRr(cur,prePos);
    }
   }
  }
 }
 return true;
}
template<typename E>
AVL_TMP<E>::iterator AVL_TMP<E>::findMax(AVL_TMP<E>::iterator pos){//以pos為根的樹的最大值的節點
 if (!pos) return NULL;
 iterator p = pos;
 while(p->rn) p = p->rn;
 return p;
}
template<typename E>
AVL_TMP<E>::iterator AVL_TMP<E>::findMin(AVL_TMP<E>::iterator pos){
 iterator p = pos;
 while (p->ln) p = p->ln;
 return p;
}
template<typename E>
void AVL_TMP<E>::updateDepth(AVL_TMP<E>::iterator pos){
 bool b1 = pos->ln == NULL,b2 = pos->rn ==NULL;
 switch(b1) {
 case true:
  if(b2) pos->depth = 0;
  else pos->depth = pos->rn->depth+1;
  break;
 default: //false
  if(b2)  pos->depth = pos->ln->depth+1;
  else pos->depth = max(pos->ln->depth , pos->rn->depth )+1;
 }
 if(pos == root) depth = pos->depth;
}
template<typename E>
void AVL_TMP<E>::LLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
 typename AVL_TMP<E>::iterator t, a = pos, b = t = pos->ln ;
 pos->ln = t->rn;
 t->rn = pos;
 if(root == a) root = b;
 if(prePos != NULL)
  if(prePos->ln == a) prePos->ln = b;
  else prePos->rn =  b;
 updateDepth(a);updateDepth(b);
}
template<typename E>
void AVL_TMP<E>::LRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
 AVL_TMP<E>::iterator a = pos,b = pos ->ln, c = b->rn;
 b->rn = c->ln ; a->ln = c->rn;
 c->ln = b;  c->rn =a;
 if(a == root ) root = c ;
 if(prePos != NULL)
  if(prePos->ln == a) prePos->ln = c;
  else prePos->rn =  c;
 updateDepth(a);updateDepth(b);updateDepth(c);
}
template<typename E>
void AVL_TMP<E>::RRr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos ){
 AVL_TMP<E>::iterator a = pos ,t, b = t = pos->rn ;
 pos->rn = t->ln;
 t->ln = pos;
 if(prePos != NULL)
  if(prePos->ln == a) prePos->ln = b;
  else prePos->rn =  b;
 if(root == a) root = b;
 updateDepth(a);updateDepth(b);
}
template<typename E>
void AVL_TMP<E>::RLr(AVL_TMP<E>::iterator pos,AVL_TMP<E>::iterator prePos){
 AVL_TMP<E>::iterator a = pos, b = pos->rn , c = b->ln;
 a->rn = c->ln ;  b->ln = c->rn;
 c->ln = a; c->rn = b;
 if(prePos != NULL)
  if(prePos->ln == a) prePos->ln = c;
  else prePos->rn =  c;
 if( a == root) root = c;
 updateDepth(a);updateDepth(b);updateDepth(c);
}
template<typename E>
bool AVL_TMP<E>::insert(const E& e){
 if(root == NULL) {root = new AVL_NODE<E>(e); size++; depth = root->depth;return true;}
 bool bUpdateDepth = false;
 vector<AVL_TMP<E>::iterator> routin;
 typename AVL_TMP<E>::iterator p = root,pos,prePos;
 for (int i = 0 ; i < size ;i++ ) {
  routin.push_back(p);
  if(p->data > e){
   if ( p->ln == NULL ) {
    p->ln = pos = new AVL_NODE<E>(e);
    bUpdateDepth = p->rn == NULL;
    break;
   }
   else { p = p->ln ; continue;}
  }
  if(p->data  < e){
   if (p->rn == NULL) {
    p->rn = pos = new AVL_NODE<E>(e) ;
    bUpdateDepth = p->ln == NULL;
    break;
   }
   else {  p = p->rn ; continue;}
  }
  return false;   //already exists
 }  //insertion finished
 size++;
 if(size <= 2 ) {
  updateDepth(root);
  return true;
 }
 if(!bUpdateDepth) return true;   //balance
 
 bool unAdjusted = true;
 // check for balance and adjust depth
 for (i = routin.size()-1; i  >=0 ; i-- ) {
  if(!balance(routin.at(i)))
   if(unAdjusted) {  //  unbalance! get unbalance type
    if(i-1 >= 0) prePos = routin.at(i-1);
    else prePos = NULL;
    AVL_TMP<E>::iterator a = routin.at(i) , b = routin.at(i+1) , c;
    if(i+2 >= routin.size() ) c = pos;
    else c = routin.at(i+2);
    bool b1,b2;
    b1 = b == a->ln;
    b2 = c == b->ln;
    unbalanceType ub;
    if(b1&&!b2)   ub = LR;
    if(!b1&&b2)   ub = RL;
    if(b1&&b2)    ub = LL;
    if(!b1&&!b2)  ub = RR;

    switch(ub) {
     case  LL :LLr(routin.at(i),prePos);
      break;
     case  LR :LRr(routin.at(i),prePos);
      break;
     case  RR :RRr(routin.at(i),prePos);
      break;
     case  RL :RLr(routin.at(i),prePos);
      break;
    }  //end switch
    unAdjusted = false;
   }  //end if
 updateDepth(routin.at(i));  //update the depth of the node in the routin
 depth = root->depth;
 }//end for
 return true;
};
template<typename E>
AVL_TMP<E>::npos AVL_TMP<E>::find(const E& e){//search for position
   npos p=root;
   while (p&&p->data!=e)
    if(e>p->data) p=p->rn;
    else p= p->ln;
   return p;
}
template<typename E>
AVL_TMP<E>::npos AVL_TMP<E>::findpre(const E& e){//search for parent node position
   npos p,pre;
   p=pre=root;
   while (p&&p->data!=e) {
    pre = p;
    if (e>p->data) p=p->rn;
    else p = p->ln;
   }
   if(p) if(p->data==e) return NULL;//already existed
   return pre;
}
template<typename E>
bool AVL_TMP<E>::delAux(E const& e,AVL_TMP<E>::iterator pos){
 // 1.遞歸刪除節點,直到刪除的是葉子節點 
 // 2. 刪除葉子節點,更新樹的數據成員
 // 3. 更新路徑上的節點深度并且檢查平衡因子 
 static vector<iterator> routine;
 iterator p = pos;
 bool bUpdate = false;
 if(!pos){//第一次調用
  p = root;
  while (p&&e!=p->data) {//找到節點,并且將尋找路徑存入表中
   routine.push_back(p);
   if(p->data > e) p = p->ln;
   else p = p->rn;
  }
  if(p == NULL){ //沒找到
   routine.clear(); 
   return false;
  }
  else pos = p;
 }
 if (pos->ln||pos->rn) {//不是葉子節點,則該節點有孩子節點,可能是一個或者兩個
  routine.push_back(pos);//還得往下刪除
  if (pos->ln&&!pos->rn){ //情況一: 只有有左孩子
   //找到左子樹中的最大值的位置
   iterator max = pos->ln;
   while (max->rn) { routine.push_back(max); max = max->rn;}
   bUpdate = false;
   //偽刪除
   pos->data = max->data;
   delAux(max->data,max);
  }
  else if (!pos->ln&&pos->rn) { //情況二:只有右孩子
   //找到右子樹中的最小值
   iterator min = pos->rn;
   while (min->ln) { routine.push_back(min); min = min->ln;}
   bUpdate = false;
   //偽刪除
   pos->data = min->data;
   delAux(min->data,min);
  }
  else //情況三:有倆個孩子
  {
   //找到左子樹中的最大值
   iterator max = pos->ln;
   while (max->rn) { routine.push_back(max); max = max->rn;}
   bUpdate = false;
   //偽刪除
   pos->data = max->data;
   delAux(max->data,max);
  }
 }
 else
 {//是葉子節點
  //有三種情況,是其父節點的左子樹且沒有兄弟,是其父節點的右子樹且沒有兄弟,有兄弟
  //取得其父節點
  iterator parent = NULL;
  if (routine.size()) //有父節點
   parent = routine[routine.size()-1];
  else{//即該節點是根節點,無根節點
   delete root;
   routine.clear();
   upTree(-1,NULL,0);
   return true;
  }  //完成根節點的刪除
  //有父節點
  if (pos == parent->ln&&!parent->rn) {//情況一:是父節點的左孩子且沒兄弟
   //刪除節點
   parent->ln = NULL;
   delete pos;
   //需要更新路徑上的節點的深度
   bUpdate = true;
   upRoutineDepth(routine);
   upTree(root->depth,root,size-1);
   routine.clear();
   //改寫父節點的孩子指針
  }//完成情況一葉子節點的刪除
  else{
   if (pos == parent->rn && !parent->ln ) { //情況二:是父節點的右孩子且沒兄弟
    parent->rn = NULL;
    delete pos; 
    bUpdate = true;
    upRoutineDepth(routine);
    upTree(root->depth,root,size-1);
    routine.clear();
   }//完成情況二葉子節點的刪除
   else{//情況三:有兄弟
    //只需要將節點刪除,并清理路徑表就可以了
    if (pos == parent->ln) parent->ln = NULL;
    else parent->rn = NULL;
    delete pos;
    routine.clear();
   }//完成情況三的葉子節點刪除
  }
 }
 return true;
}

template<typename E>
bool AVL_TMP<E>::del(dataType e){
 return delAux(e);
}

posted on 2007-10-05 15:47 zlf 閱讀(2601) 評論(2)  編輯 收藏 引用

評論

# re: AVL樹的簡單實現 2007-10-05 16:15 Minidx全文檢索

其實這樣的寫法不能算簡單拉
看看這個 http://bbs.chinaunix.net/viewthread.php?tid=692071  回復  更多評論   

# re: AVL樹的簡單實現 2007-10-06 23:05 zlf

為什么呢?
刪除操作比插入操作的代碼多
你是否會覺得更刪除更復雜呢?
其實刪除的想法是很簡單的,因為是遞歸的刪除直到遞歸到葉子節點
所以要刪除的只是葉子節點.
不管是插入還是刪除節點深度的變化都只是在插入或刪除路徑節點上
這樣更新應該很方便吧
至于旋轉操作之類的其實每必要去探討數學原理什么的
用數學來證明這東西應該很難吧(我是這么想的),要不然怎么會是兩個數學家提出來的呢?
只要知道各種不平衡類型施行的操作就行的
而操作只需要畫畫圖就很容易看出來的
也許很亂
不過這樣想來要"實現"(只是實現)AVL樹的話應該就很簡單了  回復  更多評論   


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導航

<2018年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

統計

常用鏈接

留言簿(1)

隨筆檔案

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            西西裸体人体做爰大胆久久久| 午夜电影亚洲| 日韩视频二区| 久久亚洲精选| 亚洲香蕉成视频在线观看| 嫩草伊人久久精品少妇av杨幂| 国产日韩欧美在线视频观看| 亚洲中无吗在线| 日韩网站在线观看| 欧美裸体一区二区三区| 91久久久久| 欧美福利电影网| 欧美成人免费大片| 亚洲青涩在线| 亚洲国产婷婷香蕉久久久久久| 欧美自拍丝袜亚洲| 狠狠色噜噜狠狠色综合久| 久久精品国产2020观看福利| 欧美一二三区精品| 黄色欧美成人| 欧美激情精品久久久六区热门| 裸体丰满少妇做受久久99精品| 亚洲国产女人aaa毛片在线| 欧美第十八页| 欧美日韩一区精品| 久久精品99久久香蕉国产色戒| 久久精品一区二区国产| 亚洲黄页视频免费观看| 亚洲欧洲一区二区三区| 欧美日韩亚洲一区二区三区四区 | 最新日韩欧美| 亚洲国产精品一区二区第四页av| 欧美日韩成人综合| 亚洲免费在线精品一区| 欧美淫片网站| 亚洲精品国产精品国产自| 亚洲免费高清| 好看的av在线不卡观看| 亚洲大胆人体视频| 亚洲精品1区2区| 久久久精品网| 男人插女人欧美| 亚洲一区二区三区四区五区黄 | 免费在线亚洲| 久久久精品一品道一区| 亚洲国产91| 夜夜嗨av一区二区三区中文字幕 | 欧美午夜精品一区二区三区| 午夜精品亚洲| 玖玖玖免费嫩草在线影院一区| 日韩视频免费看| 香蕉久久夜色精品| 亚洲乱亚洲高清| 欧美一级二级三级蜜桃| 日韩午夜电影av| 欧美一级理论性理论a| 亚洲精品欧美专区| 久久国产欧美| 亚洲欧美国产一区二区三区| 欧美在线观看一区二区| 99re视频这里只有精品| 久久黄色级2电影| 亚洲香蕉成视频在线观看| 久久人人精品| 欧美一区二区啪啪| 欧美日本在线看| 男女精品网站| 国产中文一区| 在线视频你懂得一区二区三区| 亚洲高清毛片| 久久久久久久999精品视频| 亚洲在线网站| 欧美日韩视频在线一区二区观看视频| 久久夜色精品亚洲噜噜国产mv | 亚洲综合欧美| 欧美日本韩国一区二区三区| 麻豆国产va免费精品高清在线| 国产精品久久久久99| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲一区精品电影| 亚洲人成在线播放网站岛国| 午夜精品区一区二区三| 亚洲线精品一区二区三区八戒| 久久综合九色综合欧美狠狠| 久久激情综合网| 国产日韩欧美日韩大片| 亚洲性感激情| 亚洲影院在线观看| 欧美私人啪啪vps| 一本色道**综合亚洲精品蜜桃冫| av成人免费在线观看| 欧美成人一区二区三区片免费| 久久久久成人精品免费播放动漫| 99av国产精品欲麻豆| 欧美插天视频在线播放| 欧美国产91| 亚洲电影在线看| 久久精品人人做人人爽电影蜜月| 欧美在线首页| 国产亚洲一级| 久久理论片午夜琪琪电影网| 浪潮色综合久久天堂| 亚洲电影在线观看| 女人香蕉久久**毛片精品| 亚洲国产成人av| 亚洲视频一起| 国产麻豆9l精品三级站| 校园春色综合网| 美国成人直播| 亚洲精品一区二区三区蜜桃久| 欧美精品精品一区| 在线一区二区三区做爰视频网站| 午夜精品99久久免费| 国内精品国产成人| 免费亚洲一区二区| 99精品国产在热久久| 午夜日本精品| 亚洲第一二三四五区| 欧美金8天国| 亚洲在线中文字幕| 久热国产精品| 日韩午夜高潮| 国产三级欧美三级日产三级99| 久久久久网址| av成人激情| 蜜臀av性久久久久蜜臀aⅴ| 亚洲美女精品成人在线视频| 国产精品午夜在线观看| 老司机精品福利视频| aⅴ色国产欧美| 久久久av网站| av成人国产| 激情欧美一区二区三区在线观看| 欧美二区在线| 香蕉久久久久久久av网站| 亚洲大胆女人| 欧美在线观看一区二区三区| 伊人天天综合| 亚洲经典视频在线观看| 亚洲另类春色国产| 国产精品国产三级国产普通话蜜臀 | 欧美日韩国产首页在线观看| 亚洲午夜av在线| 免费人成网站在线观看欧美高清| 一区二区三区视频观看| 一区二区视频欧美| 国产精品久久久久免费a∨| 久久久精彩视频| 亚洲一区欧美| 亚洲国产日韩美| 久久综合久久久久88| 亚洲主播在线播放| 99国产精品久久久久久久| 韩日精品在线| 国产女主播在线一区二区| 久久先锋影音| 亚洲欧美日韩精品在线| 欧美一级黄色网| 亚洲激情一区| 国产夜色精品一区二区av| 欧美日韩亚洲一区二区三区四区| 欧美影院成人| 午夜久久电影网| 一区二区三区.www| 亚洲精品国产欧美| 亚洲大胆在线| 欧美韩日一区| 欧美成人一区二区在线 | 亚洲午夜精品一区二区| 亚洲欧洲日本专区| 亚洲激情一区二区| 欧美国产日韩在线观看| 模特精品在线| 欧美成人中文字幕| 免费毛片一区二区三区久久久| 久久久久久久久久久久久女国产乱 | 一本一本大道香蕉久在线精品| 国产欧美日韩视频一区二区三区| 你懂的亚洲视频| 久久中文字幕一区二区三区| 久久精品主播| 久久一二三国产| 久久午夜电影网| 久久蜜桃资源一区二区老牛 | 久久这里有精品15一区二区三区| 性欧美video另类hd性玩具| 亚洲欧美日韩另类精品一区二区三区 | 亚洲精品综合久久中文字幕| 亚洲人精品午夜| 一本一本a久久| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲人成在线观看一区二区 | 国产欧美高清| 国产精品三级久久久久久电影| 国产精品高潮视频| 国产日韩一区| 亚洲高清av| 夜夜嗨网站十八久久| 亚洲一二三区在线| 久久aⅴ国产紧身牛仔裤|