//修改自《算法之美》,更易理解(自認爲)
#include<iostream>
using namespace std;
template <class T> class AvlTree;
template <class T>
class AvlNode
{
T data; //關鍵碼
AvlNode *leftChild;
AvlNode *rightChild;
int balance;//平衡因子
public:
AvlNode():leftChild(NULL),rightChild(NULL),balance(0){};
AvlNode(const T& e,AvlNode<T> *lt=NULL):
data(e),leftChild(lt),rightChild(lt),balance(0){};//默認缺省參數值
int getBalance() const { return balance;}
AvlNode<T>* getLeftChild() const{return leftChild;}
AvlNode<T>* getrightChild() const{return rightChild;}
T getData() const{return data;}
bool Insert(T x);
bool Insert(AvlNode<T> *&rt,T x,bool taller);
friend class AvlTree<T>;
};
template <class T>
class AvlTree
{ AvlNode<T> *root;
bool Insert(AvlNode<T> *& rt,T x,bool &taller);
bool Remove(AvlNode<T> * &rt,T x ,bool &shorter);
void RotateLeft(AvlNode<T> * &node);
void RotateRight(AvlNode<T> *&node);
void RightBalanceAfterInsert(AvlNode<T> * &sRoot,bool &taller);
void LeftBalanceAfterDeltete(AvlNode<T> *&sRoot,bool &shorter);
public:
AvlTree():root(NULL) {}
AvlNode<T>* getRoot() const
{return root;}
bool Insert(T x)
{ bool taller=false;
return Insert(root,x,taller);
}
bool Remove(T x)
{ bool shorter=false;
return Remove(root,x,shorter);
}
void DisplayTree(AvlNode<T> *t,int layer) const;
void DisplayTree2(AvlNode<T> *t,int layer) const;
};
//關於 Insert,如果在本節點插入後,由平衡狀態0變成+1或-1,
// 將對上一級的平衡產生影響,對應是+1或-1.
// 另一種情況是本級插入後由不平衡狀態+1、-1變成平衡0,
//對上一級的平衡狀態不產生影響。
template<typename T>
void AvlTree<T>::RotateLeft(AvlNode<T> * & node)
{ //這個左旋好複雜??
//原來的node節點的地址被上一級指向,不能更換,只能替換數據
if((node==NULL)||(node->rightChild==NULL)) return ;
AvlNode<T> * tmpNode=new AvlNode<T>(node->data);
if(tmpNode==NULL) return;
tmpNode->leftChild=node->leftChild;//新增的節點將替代node向Left下沉
node->leftChild=tmpNode;
tmpNode->rightChild=node->rightChild->leftChild;
AvlNode<T> *toDelete=node->rightChild;
node->data=toDelete->data;//node節點將被原來右子節點替代
node->rightChild=toDelete->rightChild;
delete toDelete;//刪除原來的右子結點
}
template<typename T>
void AvlTree<T>::RotateRight(AvlNode<T> *& node)
{ if((node==NULL) || (node->leftChild==NULL)) return;
AvlNode<T> *tmpNode=new AvlNode<T>(node->data);
if( tmpNode==NULL) return;
//新節點將替代node向Right下沉
tmpNode->rightChild=node->rightChild;
node->rightChild=tmpNode;
tmpNode->leftChild=node->leftChild->rightChild;
//原來的Node Left子節點轉移(上升)到Node
AvlNode<T> *toDelete=node->leftChild;
node->data=toDelete->data;
node->leftChild=toDelete->leftChild;
}
template<typename T>
bool AvlTree<T>:: Insert(AvlNode<T> *& rt,T x,bool &taller)
{//遞歸插入,成功則返回True,若插入使樹長高,taller爲true.
bool success=false;
if( rt==NULL ) //邊界條件,插入節點
{ rt=new AvlNode<T>(x);
taller=true;
return true;
}
else
{ if(x<=rt->data)
{ if( success=Insert(rt->leftChild,x,taller) )
{ switch(rt->balance)//插入左邊成功
{case 1:
if(taller) {rt->balance=0;taller=false;}
break;
case 0:
if(taller) rt->balance=-1;
break;
case -1:
if(taller) rt->balance=-2;//此處要調整
else break;
if(rt->leftChild->balance==-1)
{
RotateRight(rt);
rt->balance=0;
rt->rightChild->balance=0;
}else{ RotateLeft(rt->leftChild);
RotateRight(rt);
if(rt->balance==-1)
{ rt->leftChild->balance=0;
rt->rightChild->balance=1;
}
else{ rt->leftChild->balance=-1;
rt->rightChild->balance=0;
}
rt->balance=0;
}
taller=false;
break;
}
// if(taller) rt->balance--;
// if(rt->balance>=0) taller=false;
}
}
else if(success=Insert(rt->rightChild,x,taller))
{ switch(rt->balance)//右插成功
{ case 1:
if(taller) rt->balance=2;//此處要調整
else break;
if(rt->rightChild->balance==1)
{ RotateLeft(rt);
rt->leftChild->balance=0;
rt->balance=0;
}
else{ RotateRight(rt->rightChild);
RotateLeft(rt);
if(rt->balance==-1)
{ rt->leftChild->balance=0;
rt->rightChild->balance=1;
}
else{ rt->leftChild->balance=-1;
rt->rightChild->balance=0;
}
rt->balance=0;
}
taller=false;
break;
case 0:
if(taller) rt->balance=1;
break;
case -1:
if(taller) {rt->balance=0; taller=false;}
break;
}
// if(taller) rt->balance++;
// if(rt->balance<=0)taller=false;
}
}
return success;
}
template<typename T>
void AvlTree<T>::DisplayTree(AvlNode<T> *t,int layer) const
//深度優先,輸出信息。
{ if(t==NULL) return;
cout<<t->data<<"["<<t->balance<<"] ";
if(t->leftChild!=NULL) cout<<"left: "<<t->leftChild->data;
if(t->rightChild!=NULL) cout<<" right: "<<t->rightChild->data;
cout<<"**"<<endl;
DisplayTree(t->leftChild,layer+1);
DisplayTree(t->rightChild,layer+1);
}
template<typename T>
void AvlTree<T>::DisplayTree2(AvlNode<T> *t,int layer) const
//深度優先,輸出信息。
{ if(t==NULL) return;
cout<<t->data<<"["<<t->balance<<"]";
cout<<"(";
DisplayTree(t->leftChild,layer+1);
cout<<")";
cout<<"(";
DisplayTree(t->rightChild,layer+1);
cout<<")";
return;
}
int main()
{
AvlTree<int> a;
for(int i=1;i<=15;i++)
{ int b;
cin>>b;
a.Insert(b);
}
AvlNode<int>* rt;
rt=a.getRoot();
a.DisplayTree(rt,1);
return 0;
}
AVL樹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.