The third time:数据结构作业 ___ 二叉查找树

来源:互联网 发布:pdf编辑软件电脑版 编辑:程序博客网 时间:2024/05/16 17:59

        在上一次发完博文后,我没想到下一次再发已经是夏日炎炎的七月份,各种考试,c++大作业,还有项目,对于我这个刚刚过完大一的家伙来说压力还是蛮大的,但是我喜欢这种忙碌而又充实的感觉,今天抽空完善了了自己以前的打的代码,特此发文。

        这次要发的是二叉查找树的代码,一开始自己写了一个,但是代码冗余度实在是可怕,在参考了《数据结构与STL》(written by wiliam J.collins)之后 进行了一些代码的优化,专门设计一些成员函数来减少重复代码,但是由于代码已经整体成形,没有完全应用书中的类结构。下面是代码:

       首先是定义结点:

       

#include<iostream>#include<time.h>using namespace std;/*  ****************************************  *//*  to define the node of binary search tree  */template<typename T>struct Node{Node<T> *parent;Node<T> *lefttree;Node<T> *righttree;T Data;};
     然后是迭代器:

    

/*  **************************************** */ /*   to define the iterator of the binary search tree */
template<typename T>class Iterator{  public:<span style="white-space:pre"></span>  Node<T> *Itr;<span style="white-space:pre"></span>  Iterator(Node<T> *Ptr):Itr(Ptr){ };<span style="white-space:pre"></span>  int operator++();<span style="white-space:pre"></span>  <span style="white-space:pre"></span>  };

    迭代器重载运算符++的实现:

  

template<typename T>int Iterator<T>::operator++(){Node<T> *Temp;bool IsRightest = true;Temp = this->Itr;if(Temp->righttree != NULL){Temp = Temp->righttree;while(Temp->lefttree != NULL)Temp = Temp->lefttree;IsRightest = false;}else{while(Temp->parent != NULL){if(Temp->Data <= Temp->parent->Data ){Temp = Temp->parent;IsRightest = false;break;}Temp = Temp->parent;}}if(!IsRightest){this->Itr = Temp;return 1;}else {   cout<<"\nIt is the end of the tree!\n";    return 0;}}
   本来还应该对应的有- -运算符的重载,但是太懒没写。。。。。。

   下面就是 BinSearchTree 类的定义了:

   

/*  ****************************************  */template<typename T>class BinSearchTree{   protected:   Node<T> *Root;   unsigned Size;   public:   BinSearchTree();   ~BinSearchTree();   unsigned GetSize();   Iterator<T> find(const T& item);   Iterator<T> insert(const T& item);   //To help the function Iterator<T> insert(const T& item);   //为了减少insertleaf中的部分重复代码   Node<T>* insertleaf( Node<T>*,Node<T>*,const T &item);   void erase( Iterator<T> Itr1 );   //To help the function void erase( Iterator<T> Itr1 );   //为了减少erase中的部分重复代码   Node<T>* MoveChild( Node<T>* child, Node<T>* Itr);   Iterator<T> begin();   Iterator<T> end();};
部分成员函数的实现:

template<typename T>BinSearchTree<T>::BinSearchTree(){this->Root = NULL;this->Size = 0;}template<typename T>BinSearchTree<T>::~BinSearchTree(){this->Root = NULL;}template<typename T>unsigned BinSearchTree<T>::GetSize(){return this->Size;}

查找:

template<typename T>Iterator<T> BinSearchTree<T>::find(const T & item){Node<T> *Itr = this->Root;bool IsFound = false;while(Itr != NULL){if(Itr->Data == item){IsFound = true;break;}else if(Itr->Data < item) Itr = Itr->righttree;else Itr = Itr->lefttree;}if( IsFound ){        Iterator<T> Temp(Itr);return Temp;}else{Node<T> * NO_Found = NULL;Iterator<T> Temp(NO_Found);return Temp;}}

插入:

template<typename T>Node<T>* BinSearchTree<T>::insertleaf( Node<T>* Temp, Node<T>* parent,const T &item){Temp->Data = item;Temp->parent = parent;Temp->lefttree = NULL;Temp->righttree = NULL;if(Temp->parent->Data <item)   Temp->parent->righttree = Temp;else   Temp->parent->lefttree  = Temp;             this->Size++;return Temp;}template<typename T>Iterator<T> BinSearchTree<T>::insert(const T& item){Node<T> *Itr = this->Root; Node<T> *child = Itr;if( this->Root!=NULL )               {while(child!=NULL){Itr = child;if(Itr->Data<item) child=Itr->righttree;else child=Itr->lefttree;}Node<T> *Temp;Temp = new Node<T>;Itr = this->insertleaf(Temp,Itr,item);}else{Node<T> *RootNode;RootNode = new Node<T>;RootNode->Data = item;this->Root = RootNode;this->Root->parent = NULL;      this->Root->lefttree = NULL;     this->Root->righttree = NULL;this->Size++;}Iterator<T> Itrtemp(Itr);return Itrtemp;}

删除:

template<typename T>Node<T>* BinSearchTree<T>::MoveChild( Node<T>* child, Node<T>* Itr ){if(Itr->Data <= child->parent->Data ) child->parent->lefttree  = child;else child->parent->righttree = child;return child;}template<typename T>void BinSearchTree<T>::erase(Iterator<T> Itr1){if(Itr1.Itr==NULL)   cout<<"Can't find out the item in the tree"<<endl;else{         Node<T> *replace = NULL;   //记录替代删除节点位置的项 Node<T> *childleft  = Itr1.Itr->lefttree; Node<T> *childright = Itr1.Itr->righttree;if(childright!=NULL){childright->parent = Itr1.Itr->parent;if(childright->parent!=NULL)this->MoveChild( childright , Itr1.Itr );replace = childright;}if(childleft!=NULL){if(childright!=NULL){childleft->parent = childright;while(childleft->parent->lefttree!=NULL)childleft->parent = childleft->parent->lefttree;childleft->parent->lefttree = childleft;}else{childleft->parent = Itr1.Itr->parent;if(childleft->parent!=NULL)     replace = this->MoveChild( childleft , Itr1.Itr );}}if(replace!=NULL)   { if(Itr1.Itr==this->Root) this->Root = replace;   }else{if(Itr1.Itr->parent!=NULL){if(Itr1.Itr->Data<=Itr1.Itr->parent->Data) Itr1.Itr->parent->lefttree = NULL;else Itr1.Itr->parent->righttree = NULL;}else this->Root=NULL;}delete Itr1.Itr;this->Size--;  }}

返回最大项与返回最小项:

//返回最小项
template<typename T>Iterator<T> BinSearchTree<T>::begin(){Node<T> *Temp_left = this->Root;if(Temp_left != NULL){while( Temp_left->lefttree != NULL)Temp_left = Temp_left->lefttree;Iterator<T> Get(Temp_left);return Get;}else cout<<"The tree is empty!\n";}//返回最大项template<typename T>Iterator<T> BinSearchTree<T>::end(){Node<T> *Temp_right = this->Root;if(Temp_right!= NULL){while( Temp_right->righttree != NULL)Temp_right = Temp_right->righttree;Iterator<T> Get(Temp_right);return Get;}else cout<<"The tree is empty!\n";}

测试代码:

int main(){BinSearchTree<int> ME;    clock_t Start,Finish;int a=0;cout<<"please input the number you want to insert,input ctrl+z to end the input"<<endl;    while(cin>>a){ME.insert(a);cout<<"please input the number you want to insert,input ctrl+z to end the input"<<endl;}Start = clock();Iterator<int> Itr1 = ME.begin();Finish = clock();cout<<"Time of finding begin is: "<<(double)(Finish - Start)<<endl;#if 1Start = clock();//To traversal the binary searching treedo cout<<Itr1.Itr->Data<<" ";while(++Itr1);Finish = clock();cout<<"\nTime of reading over is: "<<(double)(Finish - Start)<<"ms"<<endl;#endifcout<<"the size of tree is:"<<ME.GetSize()<<endl;int i=1;cout<<"Please input the number you want to erase: "<<endl;while(cin>>i){ Itr1 = ME.find(i); ME.erase(Itr1); cout<<"the size of tree after erase item "<<i<<" is:"<<ME.GetSize()<<endl;}cout<<"\n";//To traversal the binary searching treeItr1 = ME.begin();do cout<<Itr1.Itr->Data<<" ";while(++Itr1);cout<<"the size of tree is:"<<ME.GetSize()<<endl;return 0;}
事实上,在书中的类中并没有 this->Root  的指向根节点的指针,取而代之的是头结点 header,书中在定义一棵空树的时候,会创建一个头结点(不带任何值),头结点的parent 用于指向根节点 , 而 lefttree 指向最小项, righttree 指向最大项 ,根节点的 parent 指向头结点。

  一开始不知道书里面把树的结构弄成这样到底什么意思,经过反复的理解和代码测试才明白这样做的好处:1,把根节点的行为与其他节点统一起来 2,查找最大项与最小项时只用耗费常数时间而不是对数时间。 虽然知道了他的好处,但是代码已成形,也没有精力引入这么一种结构了,下次有机会要尝试一下这种做法!

0 0
原创粉丝点击