您的位置:首页 > 理论基础 > 数据结构算法

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

2014-07-13 19:52 459 查看
在上一次发完博文后,我没想到下一次再发已经是夏日炎炎的七月份,各种考试,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 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,查找最大项与最小项时只用耗费常数时间而不是对数时间。 虽然知道了他的好处,但是代码已成形,也没有精力引入这么一种结构了,下次有机会要尝试一下这种做法!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: