The third time:数据结构作业 ___ 二叉查找树
2014-07-13 19:52
459 查看
在上一次发完博文后,我没想到下一次再发已经是夏日炎炎的七月份,各种考试,c++大作业,还有项目,对于我这个刚刚过完大一的家伙来说压力还是蛮大的,但是我喜欢这种忙碌而又充实的感觉,今天抽空完善了了自己以前的打的代码,特此发文。
这次要发的是二叉查找树的代码,一开始自己写了一个,但是代码冗余度实在是可怕,在参考了《数据结构与STL》(written by wiliam J.collins)之后 进行了一些代码的优化,专门设计一些成员函数来减少重复代码,但是由于代码已经整体成形,没有完全应用书中的类结构。下面是代码:
首先是定义结点:
迭代器重载运算符++的实现:
下面就是 BinSearchTree 类的定义了:
查找:
插入:
删除:
返回最大项与返回最小项:
测试代码:
一开始不知道书里面把树的结构弄成这样到底什么意思,经过反复的理解和代码测试才明白这样做的好处:1,把根节点的行为与其他节点统一起来 2,查找最大项与最小项时只用耗费常数时间而不是对数时间。 虽然知道了他的好处,但是代码已成形,也没有精力引入这么一种结构了,下次有机会要尝试一下这种做法!
这次要发的是二叉查找树的代码,一开始自己写了一个,但是代码冗余度实在是可怕,在参考了《数据结构与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 1 Start = clock(); //To traversal the binary searching tree do cout<<Itr1.Itr->Data<<" "; while(++Itr1); Finish = clock(); cout<<"\nTime of reading over is: "<<(double)(Finish - Start)<<"ms"<<endl; #endif cout<<"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 tree Itr1 = 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,查找最大项与最小项时只用耗费常数时间而不是对数时间。 虽然知道了他的好处,但是代码已成形,也没有精力引入这么一种结构了,下次有机会要尝试一下这种做法!
相关文章推荐
- The first time:数据结构作业——自定义链表及其操作
- The second time:数据结构作业 _ 栈 ( 链栈 )
- c#数据结构———二叉查找树
- 第二次数据结构作业
- 【数据结构与算法基础】二叉查找树 / Binary Search Tree
- 数据结构作业二(1)
- 数据结构作业二(2)
- c#数据结构———二叉查找树
- 数据结构查找(1)--二叉查找树
- 数据结构作业-L1
- 数据结构作业-8
- 算法学习之数据结构之二叉查找树
- 数据结构——二叉查找树
- 图解数据结构(7)——二叉查找树及平衡二叉查找树
- 数据结构作业稀疏矩阵三元组表示
- 数据结构作业-L2
- 第二次数据结构作业
- 数据结构作业串通配符匹配问题
- 数据结构作业。
- 数据结构作业—表达式求值