avl树实现

//=================avl 的异常处理类======================= //============== avl_tree_exception.h===================== #ifndef AVL_TREE_EXCEPTION_H_ #define AVL_TREE_EXCEPTION_H_ #include<stdexcept> #include<string> class ATException: public std::logic_error { public: ATException(const std::string &message="") :std::logic_error(message.c_str()) {} }; #endif


//====================avl_tree_item.h===================== //===========存放节点中数据,包含两项关键字和值========= #ifndef AVL_TREE_ITEM_H_ #define AVL_TREE_ITEM_H_ template<class ValT,class KeyT> class Item { private: ValT val; KeyT key; public: Item() {} Item(ValT &_val,KeyT &_key) :val(_val),key(_key) { } void set(ValT _val,KeyT _key) { val=_val; key=_key; } KeyT getKey()const { return key; } ValT getVal()const { return val; } }; #endif


//========================avl_tree_node.h======================== //===================avl 树的节点,包含有======================== //===========左右孩子的指针 leftPtr and rightPtr================= //=======bal 标识 该节点左右子树的相对高度LH , EH or RH========= #ifndef AVL_TREE_NODE_H_ #define AVL_TREE_NODE_H_ //mark the state of the current node //LH----left subtree is higher than right subtree 1 node; //EH----left subtree is equal to right subtree; //RH----left subtree is shorter than right subtree 1 node; #define LH +1 #define EH 0 #define RH -1 template<class ItemT,class KeyT> class AvlTree; template<class ItemT,class KeyT> class Node { private: ItemT item; Node *leftPtr,*rightPtr; int bal; Node(ItemT &_item,Node *_leftPtr,Node *_rightPtr) :item(_item),leftPtr(_leftPtr),rightPtr(_rightPtr) { bal=EH; } friend class AvlTree<ItemT,KeyT>; }; #endif


//=======================avl_tree.h====================== //======================定义avl的类====================== #ifndef AVL_TREE_H_ #define AVL_TREE_H_ #include"avl_tree_exception.h" #include"avl_tree_node.h" template<class ItemT,class KeyT> class AvlTree { public: AvlTree(); AvlTree(AvlTree &_tree); ~AvlTree(); void insert(ItemT &_item)throw(ATException); void remove(KeyT &_key)throw(ATException); void retrieve(KeyT &_key,ItemT &_item)throw(ATException); void traverse(void (*visit)(ItemT _item)); bool empty()const; protected: void insertNode(Node<ItemT,KeyT> *&treePtr,ItemT & newitem,bool &taller)throw(ATException); void removeNode(Node<ItemT,KeyT> *&treePtr,KeyT &_key,bool &shorter)throw(ATException); //当平衡的avl树经过处理(insert or delete)后,失去原有的平衡,则调用 //leftBalance 或者 rightBalance 函数处理,重新得到平衡 void leftBalance(Node<ItemT,KeyT> *&treePtr,bool &state); void rightBalance(Node<ItemT,KeyT> *&treePtr,bool &state); void rotateLeft(Node<ItemT,KeyT> *&treePtr); void rotateRight(Node<ItemT,KeyT> *&treePtr); void retrieveNode(Node<ItemT,KeyT> *&treePtr,KeyT &_key,ItemT &_item)throw(ATException); void traverseNode(Node<ItemT,KeyT> *&treePtr,void (*visit)(ItemT _item)); void copy(Node<ItemT,KeyT> *&treePtr,Node<ItemT,KeyT> *&oldPtr)throw(ATException); void destroy(Node<ItemT,KeyT> *&treePtr); private: Node<ItemT,KeyT> *root; }; #endif


//=====================avl_tree.cpp====================== //===============avl_tree.h 的实现文件=================== #include<cstddef> #include"avl_tree.h" template<class ItemT,class KeyT> AvlTree<ItemT,KeyT>::AvlTree() { root=NULL; } template<class ItemT,class KeyT> AvlTree<ItemT,KeyT>::AvlTree(AvlTree<ItemT,KeyT>& _tree) { copy(root,_tree.root); } template<class ItemT,class KeyT> AvlTree<ItemT,KeyT>::~AvlTree() { destroy(root); } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::insert(ItemT &_item) throw(ATException) { bool taller=true; try{ insertNode(root,_item,taller); }catch(ATException & e) { throw; } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::remove(KeyT &_key) throw(ATException) { bool shorter=true; try{ removeNode(root,_key,shorter); }catch(ATException &e) { throw; } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::retrieve(KeyT &_key,ItemT &_item) throw(ATException) { try{ retrieveNode(root,_key,_item); }catch(ATException &e) { throw; } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::traverse(void (*visit)(ItemT _item)) { traverseNode(root,visit); } template<class ItemT,class KeyT> bool AvlTree<ItemT,KeyT>::empty()const { return root==NULL; } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::insertNode(Node<ItemT,KeyT> *&treePtr,ItemT &newitem,bool &taller) throw(ATException) { if(treePtr==NULL) { treePtr=new Node<ItemT,KeyT>(newitem,NULL,NULL); if(treePtr==NULL) throw ATException("allocate memory faild !"); taller=true; } else if(newitem.getKey()<treePtr->item.getKey()) { insertNode(treePtr->leftPtr,newitem,taller); if(taller) { switch(treePtr->bal) { case LH:leftBalance(treePtr,taller); taller=false; break; case EH:treePtr->bal=LH; break; case RH:treePtr->bal=EH; taller=false; break; } } } else { insertNode(treePtr->rightPtr,newitem,taller); if(taller) { switch(treePtr->bal) { case LH:treePtr->bal=EH; taller=false; break; case EH:treePtr->bal=RH; break; case RH:rightBalance(treePtr,taller); taller=false; break; } } } } template<class ItemT ,class KeyT> void AvlTree<ItemT,KeyT>::removeNode(Node<ItemT,KeyT>*&treePtr,KeyT &_key,bool &shorter) throw(ATException) { if(treePtr==NULL) throw ATException("the key item not exist !"); else if(_key<treePtr->item.getKey()) { removeNode(treePtr->leftPtr,_key,shorter); if(shorter) { switch(treePtr->bal) { case LH:treePtr->bal=EH; break; case EH:treePtr->bal=RH; shorter=false; break; case RH:rightBalance(treePtr,shorter); break; } } } else if(_key>treePtr->item.getKey()) { removeNode(treePtr->rightPtr,_key,shorter); if(shorter) { switch(treePtr->bal) { case LH:leftBalance(treePtr,shorter); break; case EH:treePtr->bal=LH; shorter=false; break; case RH:treePtr->bal=EH; break; } } } else //the item who's key word equal to _key exist { Node<ItemT,KeyT> *temp; if(treePtr->leftPtr==NULL) //the node pointer treePtr only has a right subtree // or is a leaf { temp=treePtr->rightPtr; treePtr->rightPtr=NULL; delete treePtr; treePtr=temp; shorter=true; } else if(treePtr->rightPtr==NULL) //the node pointer treePtr only has a left subtree // or is a leaf { temp=treePtr->leftPtr; treePtr->leftPtr=NULL; delete treePtr; treePtr=temp; shorter=true; } else // the node pointer treePtr has both left subtree and // right subtree { temp=treePtr->rightPtr; while(temp->leftPtr!=NULL) temp=temp->leftPtr; treePtr->item=temp->item; removeNode(treePtr->rightPtr,temp->item.getKey(),shorter); if(shorter) { switch(treePtr->bal) { case LH:leftBalance(treePtr,shorter); break; case EH:treePtr->bal=LH; shorter=false; break; case RH:treePtr->bal=EH; break; } } } } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::leftBalance(Node<ItemT,KeyT> *&treePtr,bool &shorter) { Node<ItemT,KeyT> *leftTree=treePtr->leftPtr; Node<ItemT,KeyT> *rightTree=leftTree->rightPtr; switch(leftTree->bal) { case LH:treePtr->bal=EH; leftTree->bal=EH; rotateRight(treePtr); break; case EH:treePtr->bal=LH; leftTree->bal=RH; rotateRight(treePtr); shorter=false; break; case RH: { switch(rightTree->bal) { case LH:treePtr->bal=RH; leftTree->bal=EH; break; case EH:treePtr->bal=EH; leftTree->bal=EH; break; case RH:treePtr->bal=EH; leftTree->bal=LH; break; } rightTree->bal=EH; rotateLeft(leftTree); rotateRight(treePtr); break; } } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::rightBalance(Node<ItemT,KeyT>*&treePtr,bool &shorter) { Node<ItemT,KeyT> *rightTree=treePtr->rightPtr; Node<ItemT,KeyT> *leftTree=rightTree->leftPtr; switch(rightTree->bal) { case LH: { switch(leftTree->bal) { case LH:treePtr->bal=EH; rightTree->bal=RH; break; case EH:treePtr->bal=EH; rightTree->bal=EH; break; case RH:treePtr->bal=LH; rightTree->bal=EH; } leftTree->bal=EH; rotateRight(rightTree); rotateLeft(treePtr); break; } case EH:treePtr->bal=RH; rightTree->bal=LH; rotateLeft(treePtr); shorter=false; break; case RH:treePtr->bal=EH; rightTree->bal=EH; rotateLeft(treePtr); break; } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::retrieveNode(Node<ItemT,KeyT>*&treePtr,KeyT &_key,ItemT &_item) throw(ATException) { if(treePtr==NULL) throw ATException("found key item failed !"); else if(_key<treePtr->item.getKey()) { retrieveNode(treePtr->leftPtr,_key,_item); } else if(_key>treePtr->item.getKey()) { retrieveNode(treePtr->rightPtr,_key,_item); } else _item=treePtr->item; } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::traverseNode(Node<ItemT,KeyT>*&treePtr,void (*visit)(ItemT _item)) { if(treePtr!=NULL) { traverseNode(treePtr->leftPtr,visit); visit(treePtr->item); traverseNode(treePtr->rightPtr,visit); } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::copy(Node<ItemT,KeyT> *&treePtr,Node<ItemT,KeyT>*&oldPtr) throw(ATException) { if(oldPtr!=NULL) { treePtr=new Node<ItemT,KeyT>(oldPtr->item,NULL,NULL); if(treePtr==NULL) throw ATException("allocate memory failed !"); treePtr->bal=oldPtr->bal; copy(treePtr->leftPtr,oldPtr->leftPtr); copy(treePtr->rightPtr,oldPtr->rightPtr); } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::destroy(Node<ItemT,KeyT>*& treePtr) { if(treePtr!=NULL) { destroy(treePtr->leftPtr); destroy(treePtr->rightPtr); delete treePtr; treePtr=NULL; } } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::rotateLeft(Node<ItemT,KeyT> *&treePtr) { Node<ItemT,KeyT>*temp=treePtr->rightPtr; treePtr->rightPtr=temp->leftPtr; temp->leftPtr=treePtr; treePtr=temp; } template<class ItemT,class KeyT> void AvlTree<ItemT,KeyT>::rotateRight(Node<ItemT,KeyT>*&treePtr) { Node<ItemT,KeyT> *temp=treePtr->leftPtr; treePtr->leftPtr=temp->rightPtr; temp->rightPtr=treePtr; treePtr=temp; }


//=====================测试程序======================== #include<iostream> #include<string> #include<ctime> #include<cstdlib> #include"avl_tree_item.h" #include"avl_tree.h" #include"avl_tree.cpp" using namespace std; void display(Item<string,string> _item); int main() { //srand(time(0)); AvlTree<Item<string,string>,string> atree; Item<string,string> newitem; string thekey,theval; cout<<"creating avl tree atree with 100 datas !"<<endl; for(int i=0;i<100;i++) { for(int j=0;j<10;j++) { thekey=thekey+char(rand()%26+'a'); theval=theval+char(rand()%10+'0'); } newitem.set(theval,thekey); try{ atree.insert(newitem); thekey.clear(); theval.clear(); }catch(ATException &e) { cout<<e.what()<<endl; } } cout<<"the data in atree are :"<<endl; atree.traverse(display); cout<<"traverse the tree atree over !"<<endl; cout<<"enter the key word of the item (q to quit ):"<<endl; string keyword; cin>>keyword; while(keyword!="q") { try{ atree.retrieve(keyword,newitem); display(newitem); }catch(ATException &e) { cout<<e.what()<<endl; } cout<<"enter other one key (q to quit): "<<endl; cin>>keyword; } cout<<"enter the key word of the item you want to delete (s to stop):"<<endl; cin>>keyword; while(keyword!="q") { try{ atree.remove(keyword); }catch(ATException &e) { cout<<e.what()<<endl; } cout<<"enter other one key (s to stop):"<<endl; cin>>keyword; } cout<<"create a tree same as atree !"<<endl; AvlTree<Item<string,string>,string> btree(atree); cout<<"the date in btree :"<<endl; btree.traverse(display); cout<<"over !"<<endl; return 0; } void display(Item<string,string> _item) { cout<< _item.getKey()<<'\t'<<_item.getVal()<<endl; }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值