二叉树类的实现(查找树)

//stree.h

//二叉树类的实现(查找树)

//write by 宋瑞丰

/

#ifndef STREE_H

#define STREE_H

#include <exception>

#include <string>

#include <queue>

using namespace std;

 

 

 

template<typename type>

class StNode{

    public:

              type NodeValue;

              StNode<type> *m_pFather;

              StNode<type> *m_pLeft;

              StNode<type> *m_pRight;

 

              StNode(const type &item,StNode<type> *left,StNode<type> *right,StNode<type> *father)

                     :NodeValue(item),m_pLeft(left),m_pRight(right),m_pFather(father){}

};//end class StNode

 

 

 

 

template<typename type>

class Stree{

    private:

              StNode<type> *m_pRoot;

              int m_nSize;

 

              //创造新结点,并返回其指针

              //若分配内存失败,抛出异常

              StNode<type> *m_PGetAllocation

                     (const type &item,StNode<type> *left,StNode<type> *right,StNode<type> *father);

             

              StNode<type> *m_pCopy(StNode<type> * obj);

 

              StNode<type> *m_pFind(const type &item)const;

 

 

              //以降序输出二叉树

              void m_vOutByDown(StNode<type> *obj,const string &space)const;

 

              //以升序输出二叉树

              void m_vOutByRise(StNode<type> *obj,const string &space)const;

 

              //以层次输出二叉树

              void m_vOutByLayer(StNode<type> *obj,const string &space)const;

 

              //释放被删除的结点内存

              void m_vDelete(StNode<type> *obj){delete obj;}

             

              //全部删除

              void m_vDeleteAll(StNode<type> *obj){

                     StNode<type> *curr=obj;

                     if(curr!=NULL){

                            m_vDeleteAll(curr->m_pLeft);

                            m_vDeleteAll(curr->m_pRight);

                            delete curr;

                     }

              }//end m_vDeleteAll(StNode<type> *obj)

 

       public:

              class iterator{

                  private:

                            StNode<type> *m_pParent;

                            StNode<type> *m_pRootOfTree;//指向当前树的根结点

                     public:

                            iterator():m_pParent(NULL),m_pRootOfTree(NULL){}

 

                                  

                            iterator(StNode<type> * obj,StNode<type> * root)

                                   :m_pParent(obj),m_pRootOfTree(root){}

 

                            //重载操作符*

                            //如果迭代器指向end,抛出异常

                            type &operator*(){

                                   if(m_pParent==NULL)

                                          throw exception("error:operator*()const,迭代器指向无效!/n");

                             return m_pParent->NodeValue;

                            }//end operator*()const

 

                            //重载操作符==!=

                            bool operator==(const iterator &obj){return m_pParent==obj.m_pParent;}

                            bool operator!=(const iterator &obj){return m_pParent!=obj.m_pParent;}

 

                            //重载操作符--

                            //用遍历来模拟迭代的操作

                            //如果是空树,抛出异常

                            iterator operator++(){//前缀

                                   StNode<type> *root=m_pRootOfTree;

                                   StNode<type> *parent=m_pParent;

                                  

                                   //迭代器无效时

                                   if(m_pParent==NULL){

                                          //如果是空树

                                          if(root==NULL)

                                                 throw exception("error:operator++(),树为空!/n");

                                          //迭代器是由end返回的值

                                          else{

                                                 parent=root;

                                                 while(parent->m_pLeft!=NULL)//找到树中最小的结点

                                                        parent=parent->m_pLeft;

                                                 m_pParent=parent;

                                                 return iterator(m_pParent,m_pRootOfTree);//返回最小的结点

                                          }

                                   }//end if(m_pParent==NULL)

 

                                   //当迭代器的右子树存在时

                                   if(parent->m_pRight!=NULL){

                                          parent=parent->m_pRight;//运动到右子树

                                          while(parent->m_pLeft!=NULL)//查找右子树中最小结点

                                                 parent=parent->m_pLeft;

                                          m_pParent=parent;

                                          return iterator(m_pParent,m_pRootOfTree);

                                   }//end if(parent->m_pRight!=NULL)

                                  

                                   else{//迭代器右子树不存在

                                          if(parent->m_pFather==NULL){//当前结点是根结点

                                                        m_pParent=NULL;

                                                        return iterator(m_pParent,m_pRootOfTree);

                                                 }

                                          //向父结点移动直到父结点的左指针指向当前结点

                                          StNode<type> *father=parent->m_pFather;

                                          while(father->m_pLeft!=parent){

                                                 parent=parent->m_pFather;

                                                 father=parent->m_pFather;

                                                 if(parent->m_pFather==NULL){//移动到跟结点,说明迭代器已经是最大结点

                                                        m_pParent=NULL;

                                                        return iterator(m_pParent,m_pRootOfTree);

                                                 }

                                          }

                                          m_pParent=father;

                                          return iterator(m_pParent,m_pRootOfTree);

                                   }//end else

                            }//end operator++()前缀

 

                            iterator operator++(int){//后缀

                                   iterator now=*this;//取得当前的迭代器

                                   operator++();//调用前缀形式

                                   return now;

                            }//end operator++(int)后缀

 

                            iterator operator--(){//前缀

                                   StNode<type> *parent=m_pParent;

                                   StNode<type> *root=m_pRootOfTree;

                                   //如果迭代器无效时

                                   if(m_pParent==NULL){

                                          if(m_pRootOfTree==NULL)//空树

                                                 throw exception("error:operator--(),树为空!/n");

                                          else{//end返回的迭代器,将最大的结点返回

                                                 parent=root;

                                                 while(parent->m_pRight!=NULL)

                                                        parent=parent->m_pRight;

                                                 m_pParent=parent;

                                                 return iterator(m_pParent,m_pRootOfTree);

                                          }

                                   }//end if(m_pParent==NULL)

 

                                   //如果没有左结点

                                   if(m_pParent->m_pLeft==NULL){

                                          //当前结点是根结点

                                          if(parent->m_pFather==NULL){

                                                 m_pParent=NULL;

                                                 return iterator(m_pParent,m_pRootOfTree);

                                          }

                                          //向父结点查找,直到父结点的右指针指向当前结点或到达根节点

                                          StNode<type> *father=parent->m_pFather;

                                          while(father->m_pRight!=parent){

                                                        parent=parent->m_pFather;

                                                        father=parent->m_pFather;

                                                        if(parent->m_pFather==NULL){//当前结点已经是根结点

                                                               m_pParent=NULL;

                                                               return iterator(m_pParent,m_pRootOfTree);

                                                        }

                                          }

                                          m_pParent=father;

                                          return iterator(m_pParent,m_pRootOfTree);

                                   }//end if(m_pParent->m_pLeft==NULL)

 

                                   else{//有左子结点,查找左子树中最大的结点

                                          parent=parent->m_pLeft;//先移动到右结点

                                          while(parent->m_pRight!=NULL)

                                                 parent=parent->m_pRight;

                                          m_pParent=parent;

                                          return iterator(m_pParent,m_pRootOfTree);

                                   }//end else

                            }//end iterator operator--()前缀

 

 

                            iterator operator--(int){//后缀

                                   iterator now=*this;

                                   operator--();//调用前缀形式

                                   return now;

                            }//end operator--(int)后缀

              };//end class iterator

 

 

              Stree():m_pRoot(NULL),m_nSize(0){}

 

              //复制构造函数

              Stree(const Stree& obj);

 

              //构造函数

              Stree(type * start,type * end);

 

              //重载赋值操作符

              Stree<type> &operator=(const Stree<type> & obj);

 

              //察看二叉树是否为空

              bool m_bEmpty()const{return m_nSize==0;}

 

              //返回二叉树结点的个数

              int m_nGetSize()const{return m_nSize;}

 

              //返回遍历中第一项的迭代器

              iterator m_itBegin();

               

              const iterator m_itBegin()const;

 

              //返回遍历结束后的第一个位置的迭代器

              iterator m_itEnd();

 

              const iterator m_itEnd()const;

 

              //查找二叉树中的节点,返回迭代器

              //如果没找到,返回m_itEnd()

              iterator m_itFind(const type & item)const

              {

                     return iterator(m_pFind(item),m_pRoot);

              }

 

              //向树中插入一个结点

              //返回迭代器和插入是否成功的bool指示的pair类型

              pair<iterator,bool> m_Insert(const type &item);

 

              //从树中删除一个结点

              //如果树为空,抛出异常

              bool m_bEraser(const type & item);

 

              bool m_bEraser(iterator pos);

 

              void m_bEraser(iterator start,iterator end);

 

 

 

              //输出,用123选择输出方式

              //1:降序,2:升序,3:层次

              void m_vOutPut(int choice,const string & space="  "){

                     if(m_nSize==0)

                            return ;

                    

                     if(choice==1)

                            m_vOutByDown(m_pRoot,space);

                     if(choice==2)

                            m_vOutByRise(m_pRoot,space);

                     if(choice==3)

                            m_vOutByLayer(m_pRoot,space);

              }//end m_vOut(int choice)

 

 

              //清空树

              void m_vClear(){

                     m_vDeleteAll(m_pRoot);

                     m_nSize=0;

              }

              //析构函树

              ~Stree(){

                     if(m_nSize!=0)

                            m_vClear();

              }

 

};//end class Stree

 

 

//函数实现

 

 

 

template<typename type>

StNode<type> *Stree<type>::m_PGetAllocation

            (const type &item,StNode<type> *left,StNode<type> *right,StNode<type> *father)

{

       StNode<type> *newNode=new StNode<type>(item,left,right,father);

       if(newNode==NULL)

              throw exception("error:m_PGetAllocation,内存分配失败!/n");

       return newNode;

}//end m_PGetAllocation(const type& item)

 

 

template<typename type>

StNode<type> *Stree<type>::m_pCopy(StNode<type> * obj)

{

       StNode<type> *newNode;

       StNode<type> *root=obj;

       StNode<type> *left,*right;

       if(root!=NULL){

              if(root->m_pLeft!=NULL)

                     left=m_pCopy(root->m_pLeft);

              else left=NULL;

              if(root->m_pRight!=NULL)

                     right=m_pCopy(root->m_pRight);

              else right=NULL;

       }

       newNode=m_PGetAllocation(root->NodeValue,left,right,NULL);

       if(newNode->m_pLeft!=NULL)//给父指针赋值

              newNode->m_pLeft->m_pFather=newNode;

       if(newNode->m_pRight!=NULL)

              newNode->m_pRight->m_pFather=newNode;

       return newNode;

}//end m_pCopy(StNode<type> * obj)

 

 

template<typename type>

StNode<type> *Stree<type>::m_pFind(const type &item)const

{

       StNode<type> *curr=m_pRoot;

       while(curr!=NULL){

              if(curr->NodeValue==item)

                     return curr;

              if(curr->NodeValue<item){

                     curr=curr->m_pRight;

                     continue;

              }

              if(curr->NodeValue>item){

                     curr=curr->m_pLeft;

                     continue;

              }

       }

       return NULL;

}//end Stree::m_pFind(const type &item)const

 

 

template<typename type>

Stree<type>::Stree(const Stree& obj)

{

       m_nSize=obj.m_nSize;

       m_pRoot=m_pCopy(obj.m_pRoot);

}//end Stree(const Stree& obj)

 

 

template<typename type>

Stree<type>::Stree(type * start,type * end):m_nSize(0)

{

       type *curr=start;

       while(curr!=end){

              m_Insert(*curr);

              curr++;

       }

}//end Stree(type * start,type * end)

 

 

template<typename type>

Stree<type> &Stree<type>::operator =(const Stree<type> &obj)

{

       if(m_pRoot==obj.m_pRoot)

              return *this;

       m_vClear();

       m_nSize=obj.m_nSize;

       m_pRoot=m_pCopy(obj.m_pRoot);

       return *this;

}//end operator =(const Stree<type> &obj)

 

 

 

template<typename type>

pair<Stree<type>::iterator,bool> Stree<type>::m_Insert(const type &item)

{

      

       if(m_nSize==0){

           m_pRoot=m_PGetAllocation(item,NULL,NULL,NULL);

              m_nSize++;

              return pair<iterator,bool>(iterator(m_pRoot,m_pRoot),true);

       }

       StNode<type> *curr=m_pRoot;

       StNode<type> *newNode;

       while(1){

              if(curr->NodeValue==item)

                     return pair<iterator,bool>(iterator(NULL,m_pRoot),false);

 

              if(curr->NodeValue>item){

                     if(curr->m_pLeft==NULL){

                            newNode=m_PGetAllocation(item,NULL,NULL,curr);

                            curr->m_pLeft=newNode;

                            m_nSize++;

                            return pair<iterator,bool>(iterator(newNode,m_pRoot),true);

                     }

                     else curr=curr->m_pLeft;

              }//end if(curr->NodeValue>item)

 

              if(curr->NodeValue<item){

                     if(curr->m_pRight==NULL){

                            newNode=m_PGetAllocation(item,NULL,NULL,curr);

                            curr->m_pRight=newNode;

                            m_nSize++;

                            return pair<iterator,bool>(iterator(newNode,m_pRoot),true);

                     }

                     else curr=curr->m_pRight;

              }//end     if(curr->NodeValue<item)

       }

}//end m_Insert(const type &item)

 

 

 

template<typename type>

bool Stree<type>::m_bEraser(const type & item)

{//删除算法需要维护树的有序性,分几种情况考虑

       StNode<type> *now=m_pFind(item);

       if(now==NULL)//无此数

              return false;

       StNode<type> *father;

       //1,此结点是叶结点

       if(now->m_pLeft==NULL && now->m_pRight==NULL){

              if(now->m_pFather==NULL){//只有这一个结点

                     delete now;

                     m_pRoot=NULL;

                     m_nSize--;

                     return true;

              }

              else{//普通叶结点

                     father=now->m_pFather;

                     if(father->m_pLeft==now)

                            father->m_pLeft=NULL;

                     if(father->m_pRight==now)

                            father->m_pRight=NULL;

                     delete now;

                     m_nSize--;

                     return true;

              }

       }//end 1

 

       //2,有左子树,无右子树

       if(now->m_pLeft!=NULL && now->m_pRight==NULL){

              if(now->m_pFather==NULL){//是根结点

                     now->m_pLeft->m_pFather=NULL;

                     m_pRoot=now->m_pLeft;

                     delete now;

                     m_nSize--;

                     return true;

              }

              father=now->m_pFather;

              if(father->m_pLeft==now){//原来是连接在父结点的左边

                     father->m_pLeft=now->m_pLeft;

                     now->m_pLeft->m_pFather=father;

                     delete now;

                     m_nSize--;

                     return true;

              }

              if(father->m_pRight==now){//原来是连接在父结点的右边

                     father->m_pRight=now->m_pLeft;

                     now->m_pLeft->m_pFather=father;

                     delete now;

                     m_nSize--;

                     return true;

              }

       }//end 2

 

       //3,有右子树,没有左子树

       if(now->m_pRight!=NULL &&now->m_pLeft==NULL){

              if(now->m_pFather==NULL){//是根结点

                     now->m_pRight->m_pFather=NULL;

                     m_pRoot=now->m_pRight;

                     delete now;

                     m_nSize--;

                     return true;

              }

              father=now->m_pFather;

              if(father->m_pLeft==now){//原来是连接在父结点的左边

                     father->m_pLeft=now->m_pRight;

                     now->m_pRight->m_pFather=father;

                     delete now;

                     m_nSize--;

                     return true;

              }

              if(father->m_pRight==now){//原来是连接在父结点的右边

                     father->m_pRight=now->m_pRight;

                     now->m_pRight->m_pFather=father;

                     delete now;

                     m_nSize--;

                     return true;

              }

       }//end 3

 

 

       //4,既有左子树,又有右子树

       //采用方法:将左子树接在右子树最左节点上

       if(now->m_pLeft!=NULL && now->m_pRight!=NULL){

              StNode<type> *leftTree=now->m_pLeft;

              StNode<type> *rightTree=now->m_pRight;

              StNode<type> *deleteNow=now;

              //将左子树连到右子树最左节点

              now=now->m_pRight;

              while(now->m_pLeft!=NULL){//寻找最左节点

                     now=now->m_pLeft;

              }

              now->m_pLeft=leftTree;

              leftTree->m_pFather=now;

              //将右子树和目标节点的父节点相连

              if(deleteNow->m_pFather!=NULL){

                     father=deleteNow->m_pFather;

                     if(father->m_pLeft==deleteNow){

                            //如果now节点连接father节点左端,将now的右节点和father节点左端连接

                            father->m_pLeft=rightTree;

                            rightTree->m_pFather=father;

                     }

                     if(father->m_pRight==deleteNow){

                            father->m_pRight=rightTree;

                            rightTree->m_pFather=father;

                     }

              }

              else {

                     rightTree->m_pFather=NULL;

                     m_pRoot=rightTree;

              }

 

              delete deleteNow;

              m_nSize--;

              return true;

       }//end 4

       return false;

 

}//end m_bEraser(const type & item)

 

 

 

 

template<typename type>

bool Stree<type>::m_bEraser(iterator pos)

{

       type item=*pos;

       return m_bEraser(item);

}//end m_bEraser(iterator pos)

 

 

 

template<typename type>

void Stree<type>::m_bEraser(iterator start,iterator end)

{

       iterator curr=start;

       while(curr!=end)

              m_bEraser(curr++);

}//end m_bEraser(iterator start,iterator end)

 

 

 

template<typename type>

void Stree<type>::m_vOutByDown(StNode<type> *obj,const string &space)const

{

       if(obj!=NULL){

              m_vOutByDown(obj->m_pRight,space);

              std::cout<<obj->NodeValue<<space;

              m_vOutByDown(obj->m_pLeft,space);

       }

}//end m_vOutByDown(StNode<type> *obj)const

 

 

 

template<typename type>

void Stree<type>::m_vOutByRise(StNode<type> *obj,const string &space)const

{

       if(obj!=NULL){

              m_vOutByRise(obj->m_pLeft,space);

              std::cout<<obj->NodeValue<<space;

              m_vOutByRise(obj->m_pRight,space);

       }

}//end m_vOutByRise(StNode<type> *obj)const

 

 

template<typename type>

void Stree<type>::m_vOutByLayer(StNode<type> *obj,const string &space)const

{

       StNode<type> *curr=obj;

       queue<StNode<type> *> que;

       que.push(curr);//先将一个节点入队

       while(!que.empty()){

              curr=que.front();

              cout<<curr->NodeValue<<space;

              que.pop();

 

              if(curr->m_pLeft!=NULL)

                     que.push(curr->m_pLeft);

              if(curr->m_pRight!=NULL)

                     que.push(curr->m_pRight);

       }

}//end m_vOutByLayer(StNode<type> *obj)const

 

 

 

template<typename type>

Stree<type>::iterator Stree<type>::m_itBegin()

{

       if(m_pRoot==NULL)

              return m_itEnd();

       StNode<type> *curr=m_pRoot;

       while(curr->m_pLeft!=NULL)

              curr=curr->m_pLeft;

       return iterator(curr,m_pRoot);

}//end m_itBegin()const

 

 

template<typename type>

Stree<type>::iterator Stree<type>::m_itEnd()

{

       return iterator(NULL,m_pRoot);

}//end m_itEnd()

 

 

template<typename type>

const Stree<type>::iterator Stree<type>::m_itBegin()const

{

       if(m_pRoot==NULL)

              return m_itEnd();

       StNode<type> *curr=m_pRoot;

       while(curr->m_pLeft!=NULL)

              curr=curr->m_pLeft;

       return iterator(curr,m_pRoot);

}//end m_itBegin()const

 

 

template<typename type>

const Stree<type>::iterator Stree<type>::m_itEnd()const

{

       return iterator(NULL,m_pRoot);

}//end m_itEnd()

 

 

 

#endif//end STREE_H

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值