//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);
//输出,用1,2,3选择输出方式
//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