您的位置:首页 > 编程语言 > C语言/C++

用C++实现二叉树(转)

2009-04-20 14:14 417 查看
二叉树是一个非常重要的数据结构,很多教材上并没有提到如何通过字符串或者其他形式来生成二叉树。
本人实现的二叉树类提供了如下功能
1:由前序字串生成二叉树
2:由后续字串生成二叉树
3:提供三种迭代器,用于遍历二叉树
文件 test.cpp 是对二叉树接口的测试,文件BinaryTree.h是二叉树模板的实现,其中用到了链栈,myStack.h 在以前的文章提到过,并且也提供了代码

在BinaryTree.h 定义了几个类
BinTreeNode :二叉树节点类,带父节点
BinaryTree : 二叉树类
BinaryTree::iterator; //迭代器基类
BinaryTree::PreOrder_iterator; //前序迭代器
BinaryTree::InOrder_iterator; //中序迭代器
BinaryTree::PostOrder_iterator; //后序迭代器
* Copyright (c) 2006
* Jacky Wu
* You can use these source code for any purpose.
* And It is provided "as is" without express or implied warranty.
*
* 你可以任意使用该代码,但是本人不对代码的安全性做任何担保!!!
*
* 由于大部分代码是出于学习目的实现的,只是让它“可以使用",
* 并没有经过安全性,高负荷运行强度等测试,我必须对这些代码做一个声明:
* !!!!
* 免责声明:
* 对于使用在本blog上提供的任意“形式”(包括测试,类的实现,
* 系统的分析 等等只要是代码片断)的代码造成系统不稳定或者
* 由于此造成的经济、声誉上的损失,或者是人身伤害等任何损失,本人不负任何法律责任

//文件 test.cpp

#include "BinaryTree.h"

#include <iostream>

using namespace std;

int main()
{
BinaryTree<char> tree;

//前序字符串
string str = "ABC#D##E#F##GH#I##JK##L##";

//后续字符串
//string str = "###DC###FEB###IH##K##LJGA";

//前序方法生成二叉树
tree.PreOrderCreateTree(str);

cout << "EXP STR: " << str << endl;

//前序方法遍历打印二叉树
tree.PreOrder();

//中序打印二叉树
tree.InOrder();

//后续打印二叉树
tree.PostOrder();

cout << "Tree Height:" << tree.Height() << endl;
cout << "Tree Height:" << tree.Size() << endl;

//二叉树拷贝构造调用
BinaryTree<char> tree2 = tree;
tree2.PreOrder();

cout << "PreOrder iteraotr!/n";

//二叉树前序迭代器
BinaryTree<char>::PreOrder_iterator preiter(tree2);
while(!preiter.IsEnd())
{

cout << *preiter << ",";
++preiter;
}
cout << endl;

//二叉树中序迭代器
tree.InOrder();
cout << "InOrder iteraotr!/n";
BinaryTree<char>::InOrder_iterator initer(tree2);
while(!initer.IsEnd())
{

cout << *initer << ",";
++initer;
}

//二叉树后续迭代器
cout << endl;
tree2.PostOrder();
cout << "PostOrder iteraotr!/n";
BinaryTree<char>::PostOrder_iterator postiter(tree2);

while(!postiter.IsEnd())
{

cout << *postiter << ",";
++postiter;
}

return 0;
}
//文件BinaryTree.h

#ifndef BINARYTREE_H_
#define BINARYTREE_H_

#include "myStack.h"

#include <string>
#include <iostream>
#include <stdexcept>

enum ChildID { LEFTCHILD = 0, RIGHTCHILD }; //子节点类型,是左节点还是右节点

template <class Type> class BinaryTree;

//愚认为,如果BinTreeNode中的数据需要让大部分用户访问的话,应当是struct型
template <class Type>
class BinTreeNode {
friend class BinaryTree< Type >;
public:
BinTreeNode() : m_pParent(0), m_plChild(0), m_prChild(0){}

BinTreeNode( Type item,
BinTreeNode<Type> *parent = 0,
BinTreeNode<Type> *left = 0,
BinTreeNode<Type> *right = 0
) : m_pParent(parent),
m_plChild(left),
m_prChild(right),
m_data(item) {}

Type GetData() const; //获取节点保存的数据
Type& GetDataRef(); //不应当提供这样的接口,这里仅仅让iterator能够自由访问存储的数据
BinTreeNode* GetParent() const; //获取节点的父节点
BinTreeNode* GetLeft() const; //获取节点的左子节点
BinTreeNode* GetRight() const; //获取节点的右子节点

void SetData( const Type& data ); //修改节点的数据

//下面是更改节点的指针域结构的function,是否真的需要,还得仔细考量
//做为树的节点,一般不允许直接访问节点中的指针数据,如果这些数据在树
//被建立完成以后修改,会破坏树的结构

void SetParent( BinTreeNode<Type>* parent, ChildID CHID ); //设置当前节点的父节点,并指定当前节点作为子节点的类型
void SetLeft( BinTreeNode<Type>* left); //设置当前节点的左子节点
void SetRight( BinTreeNode<Type>* right); //设置当前节点的右子节点

private:
BinTreeNode< Type >* m_pParent; //父节点
BinTreeNode< Type >* m_plChild; //left Child
BinTreeNode< Type >* m_prChild; //right Child
Type m_data;
};
//declare BinTreeNode end

//*********************************************************
// BinTreeNode Implementation
//*********************************************************
template <class Type>
Type
BinTreeNode<Type>::GetData() const
{
return m_data;
}

template <class Type>
Type&
BinTreeNode<Type>::GetDataRef()
{
return m_data;
}

template <class Type>
BinTreeNode<Type>*
BinTreeNode<Type>::GetParent() const
{
return m_pParent;
}

template <class Type>
BinTreeNode<Type>*
BinTreeNode<Type>::GetLeft() const
{
return m_plChild;
}

template <class Type>
BinTreeNode<Type>*
BinTreeNode<Type>::GetRight() const
{
return m_prChild;
}

template <class Type>
void BinTreeNode<Type>::SetData( const Type& data )
{
m_data = data;
}

template <class Type>
void
BinTreeNode<Type>::SetParent( BinTreeNode<Type>* parent, ChildID CHID )
{
if( !parent ) return;

if( CHID == m_plChild ) //当前节点作为parent的左子节点
{
m_pParent = parent;
parent->m_plChild = this;
}
else if( CHID == RIGHTCHILD ) //当前节点作为parent的右子节点
{
m_pParent = parent;
parent->m_prChild = this;
}
}

template <class Type>
void BinTreeNode<Type>::SetLeft( BinTreeNode<Type>* left)
{
m_plChild = left;
}

template <class Type>
void BinTreeNode<Type>::SetRight( BinTreeNode<Type>* right)
{
m_prChild = right;
}

// BinTreeNode Implementation over
//*********************************************************
//*********************************************************

template <class Type>
class BinaryTree {
public:
BinaryTree() : root(NULL) {}
BinaryTree( Type value) : RefValue(value), root(NULL) {}

BinaryTree( const BinaryTree<Type>& tree); //copy Constructure privated
BinaryTree<Type>& operator=( const BinaryTree<Type>& tree); //operator= privated

virtual ~BinaryTree();
virtual int IsEmpty() { return root == NULL; }

/*
* 下面三个函数的可用性,返回值类型的正确性值得考量
* 这样做不仅会破坏树的结构,而且很容易引起内存泄漏
* 在一般的树中最好不要提供这三个接口
*/
virtual BinTreeNode<Type>* Parent( BinTreeNode<Type>* current ); //返回所给结点父结点

virtual BinTreeNode<Type>* LeftChild( BinTreeNode<Type>* current); //返回节点的左子积极淡

virtual BinTreeNode<Type>* RightChild( BinTreeNode<Type>* current); //返回节点的右子女

virtual bool Insert( const Type& item); //插入元素
virtual bool Find( const Type& item) const; //搜索元素

const BinTreeNode<Type>* GetRoot() const; //取树根

//遍历操作
void PreOrder() const; //前序
void InOrder() const; //中序
void PostOrder() const; //后序

//二叉树特性操作函数
int Size() const;
int Size( const BinTreeNode<Type>* troot) const;
int Height() const;
int Height( const BinTreeNode<Type>* troot) const;
bool operator==( const BinaryTree<Type>& tree) const;

//下面的接口是以不同的方式来构建二叉树
BinaryTree<Type>& AutoCreateTree(const std::string& expstr); //自动判断格式并建立
BinaryTree<Type>& PreOrderCreateTree(const std::string& expstr); //先序建立
BinaryTree<Type>& PostOrderCreateTree(const std::string& expstr); //后续建立

protected:
BinTreeNode< Type>* Parent( BinTreeNode<Type>* start, BinTreeNode<Type>* current );
int Insert( BinTreeNode<Type>* current, const Type& item);
void Travers( BinTreeNode<Type>* current, std::ostream& out ) const;
void Find( BinTreeNode<Type>* current, const Type& item ) const;
void destroy( BinTreeNode<Type>* current);

//遍历递归
void InOrder( BinTreeNode<Type>* current) const;
void PreOrder( BinTreeNode<Type>* current ) const;
void PostOrder( BinTreeNode<Type>* current) const;

//二叉树特性递归操作函数
BinTreeNode<Type>* Copy( BinTreeNode<Type>* troot, BinTreeNode<Type>* parent);
bool equal( BinTreeNode<Type>* troot1, BinTreeNode<Type>* troot2) const;

//建树用的递归函数
BinTreeNode<Type>* PreOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent); //先序递归建立二叉树
BinTreeNode<Type>* PostOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent); //后续递归建立二叉树

//声明一组用于二叉树的迭代器iterator
private:
class iterator; //迭代器基类
friend class iterator;
public:

class PreOrder_iterator; //前序迭代器
class InOrder_iterator; //中序迭代器
class PostOrder_iterator; //后序迭代器
class LevelOrder_iterator; //层序迭代器

friend class PreOrder_iterator;
friend class InOrder_iterator;
friend class PostOrder_iterator;
friend class LevelOrder_iterator;

private:
BinTreeNode< Type >* root; //树的根指针
Type RefValue; //数据输入终结标志
};
//END BinaryTree

/**********************************
* implament of template BinaryTree
*
**********************************/

template <class Type>
BinaryTree<Type>::BinaryTree( const BinaryTree<Type>& tree) //copy Constructure privated
{
root = Copy(tree.root, NULL);
}

template <class Type>
BinaryTree<Type>& BinaryTree<Type>::operator=( const BinaryTree<Type>& tree) //operator= privated
{
destroy(root);
root = Copy(tree.root, NULL);
return *this;
}

template <class Type>
BinaryTree<Type>::~BinaryTree()
{
destroy(root); //遍历删除二叉树
}

template <class Type>
bool BinaryTree<Type>::Insert( const Type& item)
{

return true;
}

template <class Type>
bool BinaryTree<Type>::Find( const Type& item) const
{
return true;
}

template <class Type>
BinTreeNode<Type>* BinaryTree<Type>::Parent( BinTreeNode<Type>* current)
{
if( root == NULL || root == current )
{
return NULL;
}
else
{
return current->m_pParent;
}

/*
* 由于节点保留了parent的地址,所以可以直接取得父节点的地址
* 但是节点中如果没有parent的数据,就必须调用递归查询来寻找父节点的地址
* 代码片断如下,它调用了Parent( BinTreeNode<Type> *start, BinTreeNode<Type>* current)

return (root == NULL || root == current) ? NULL : Parent( root, current);

*/
}

template <class Type>
BinTreeNode<Type>* BinaryTree<Type>::LeftChild( BinTreeNode<Type>* current)
{
return current != NULL ? current->m_plChild : NULL;
}

template <class Type>
BinTreeNode<Type>* BinaryTree<Type>::RightChild( BinTreeNode<Type>* current)
{
return current != NULL ? current->m_prChild : NULL;
}

template <class Type>
BinTreeNode<Type>* BinaryTree<Type>::Parent( BinTreeNode<Type> *start,
BinTreeNode<Type>* current)
{
//从结点start开始,搜索节点current的父结点,
//如果找到其父节点,则函数将其返回,否则返回 NULL
if( !start ) return NULL;
if( start->m_plChild == current || start->m_prChild == current)
return start;

BinTreeNode<Type> *pNode;
if((pNode = Parent( start->m_plChild, current)) != NULL)
{
return pNode;
}
else
{
return Parent( start->m_prChild, current);
}
}

template <class Type>
const BinTreeNode<Type>* BinaryTree<Type>::GetRoot() const
{
return root;
}

template <class Type>
void BinaryTree<Type>::Travers( BinTreeNode<Type>* current, std::ostream& out) const
{
//前序输出根为current的二叉数
if( current ) {
out << current->m_data;
Travers( current->m_plChild , out );
Travers( current->m_prChild, out );
}
else
{
out<<"#";
}
}

//中序遍历操作
template <class Type>
void BinaryTree<Type>::InOrder() const
{
std::cout << "InOrder Traval Tree:/n";
InOrder( root );
std::cout << std::endl;
}

template <class Type>
void BinaryTree<Type>::InOrder( BinTreeNode<Type>* current) const
{
//递归私有函数,中序遍历二叉树
if(current != NULL) {
InOrder(current->m_plChild);
std::cout << current->m_data;
InOrder(current->m_prChild);
}
else
{
std::cout << "#";
}
}

//前序遍历操作
template <class Type>
void BinaryTree<Type>::PreOrder() const
{
std::cout << "PreOrder Travel Tree:/n";
PreOrder (root);
std::cout << std::endl;
}

template <class Type>
void BinaryTree<Type>::PreOrder( BinTreeNode<Type>* current) const
{
if(current != NULL) {
std::cout << current->m_data;
PreOrder(current->m_plChild);
PreOrder(current->m_prChild);
}
else
{
std::cout <<"#";
}
}

//后序遍历操作
template <class Type>
void BinaryTree<Type>::PostOrder() const
{
//后序遍历
std::cout << "PostOrder Travel Tree:/n";
PostOrder(root);
std::cout << std::endl;
}

template <class Type>
void BinaryTree<Type>::PostOrder( BinTreeNode<Type>* current) const{
//后序递归操作

if( current != NULL ) {
PostOrder(current->m_plChild);
PostOrder(current->m_prChild);
std::cout << current->m_data;
}
else
{
std::cout << "#";
}
}

//计算二叉树的结点数
template <class Type>
int BinaryTree<Type>::Size() const
{
return Size(root);
}

template <class Type>
int BinaryTree<Type>::Size( const BinTreeNode<Type>* troot) const
{
if(troot == NULL) return 0; //空树,返回0
else return 1 + Size(troot->m_plChild) + Size(troot->m_prChild);

}

//计算二叉树的高度
template <class Type>
int BinaryTree<Type>::Height() const
{
return Height(root);
}

template <class Type>
int BinaryTree<Type>::Height( const BinTreeNode<Type>* troot) const
{
if ( troot == NULL ) return -1;
else return 1 + MAX( Height( troot->m_plChild ) , Height( troot->m_prChild) );
}

//用于递归拷贝的私有函数
template <class Type>
BinTreeNode<Type>* BinaryTree<Type>::Copy( BinTreeNode<Type>* troot, BinTreeNode<Type>* parent)
{
if (NULL == troot) return NULL;
BinTreeNode<Type>* pNode = new BinTreeNode<Type>;
pNode->m_data = troot->m_data; //拷贝数据
pNode->m_pParent = parent;
pNode->m_plChild = Copy( troot->m_plChild, pNode ); //新建左子树
pNode->m_prChild = Copy( troot->m_prChild, pNode ); //新建右子树
return pNode; //返回树根结点
}

//判断二叉树内容是否相等
template <class Type>
bool BinaryTree<Type>::operator==( const BinaryTree<Type>& tree) const
{
return equal( root, tree.root );
}

//判断二叉树相等的递归操作
template <class Type>
bool BinaryTree<Type>::equal( BinTreeNode<Type>* troot1, BinTreeNode<Type>* troot2) const
{
if( NULL == troot1 && NULL == troot2 ) return true;
if( (NULL == troot1 && NULL != troot2)
|| (NULL != troot1 && NULL == troot2)
|| (troot1->data != troot2->data) ) {
return false;
}
else {
return equal( troot1->m_plChild, troot2->m_plChild) && equal( troot1->m_prChild, troot2->m_prChild);
}
return true;
}

template <class Type>
void BinaryTree<Type>::destroy( BinTreeNode<Type>* current) {
if( current ) {
destroy( current->m_plChild ); //递归删除左结点
destroy( current->m_prChild); //除右节点
delete current;
current = NULL; //空置指针
}
}

//define of Max function
template <class _T>
_T MAX(const _T& a, const _T& b)
{
return (a>=b) ? a : b;
}

//*********************************************************
//1:先序方式建立二叉树

template <class Type>
BinaryTree<Type>&
BinaryTree<Type>::PreOrderCreateTree(const std::string& expstr)
{
using namespace std;

const char* exp = expstr.c_str();
if(*exp != '#') //以#开头表示字符串不是先序表达式
{
destroy(root);
root = PreOrderCreateNode(exp, NULL);
}
else
{
cout << "Your string expression error, I can't Create B-Tree :)/n";
}

return *this;
}

template <class Type>
BinTreeNode<Type>*
BinaryTree<Type>::PreOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent)
{
if( *expstr == '#' || *expstr == '/0') return NULL;
BinTreeNode<Type>* pnewNode = new BinTreeNode<Type>(*expstr, parent);

assert(pnewNode);

pnewNode->m_plChild = PreOrderCreateNode(++expstr, pnewNode);
pnewNode->m_prChild = PreOrderCreateNode(++expstr, pnewNode);
return pnewNode;
}

//*********************************************************

//*********************************************************

//3:后续方式建立二叉树
template <class Type>
BinaryTree<Type>&
BinaryTree<Type>::PostOrderCreateTree(const std::string& expstr)
{
using namespace std;
const char* exp = expstr.c_str();
if( expstr.size() < 3)
{
destroy(root);
return *this;
}

if(*exp == '#' && *(exp+1) == '#' && *(exp+2) == '#' ) //以 ##'X' 开头表示字符串是后续序表达式 'X'表示元素
{
destroy(root);
exp += expstr.size()-1;
root = PostOrderCreateNode(exp, NULL); //反向遍历生成
}
else
{
cout << "Your string expression error, I can't Create B-Tree :)/n";
}

return *this;

}

template <class Type>
BinTreeNode<Type>*
BinaryTree<Type>::PostOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent)
{
if( *expstr == '#') return NULL;
BinTreeNode<Type>* pnewNode = new BinTreeNode<Type>(*expstr, parent);

assert(pnewNode);
pnewNode->m_prChild = PostOrderCreateNode(--expstr, pnewNode);

pnewNode->m_plChild = PostOrderCreateNode(--expstr, pnewNode);

return pnewNode;
}

//********************************************************
//********************************************************
//三种迭代器的实现

//iterator 是私有的基类迭代器,这里没有实现常量树的迭代器 const_iterator
//这样做确保了用户不可能访问到这个迭代器
template <class Type>
class BinaryTree<Type>::iterator {
public:
iterator():m_btree(NULL), m_pCurrent(NULL){}
virtual ~iterator() {}

virtual iterator& operator= (const iterator& iter)
{
m_pCurrent = iter.m_pCurrent;
return *this;
}

virtual iterator& GotoFirst() = 0; //游标索引到第一个节点
virtual bool IsEnd() = 0; //游标是否已经索引到末尾

virtual iterator& operator++() = 0; // 游标自增
//virtual iterator operator++(int) = 0;

virtual const Type& current() const;
virtual Type& operator*();
virtual Type* operator->();
protected:
BinaryTree<Type>* m_btree;
BinTreeNode<Type>* m_pCurrent;
};

template <class Type>
const Type&
BinaryTree<Type>::iterator::current() const
{
if(m_pCurrent != NULL)
{
return m_pCurrent->GetDataRef();
}
else
{
throw std::out_of_range("iterator error/n");
}
}

template <class Type>
Type&
BinaryTree<Type>::iterator::operator*()
{
if(m_pCurrent != NULL)
{
return m_pCurrent->GetDataRef();
}
else
{
throw std::out_of_range("iterator error/n");
}
}

template <class Type>
Type*
BinaryTree<Type>::iterator::operator->()
{
if(m_pCurrent != NULL)
{
return &(m_pCurrent->GetDataRef());
}
else
{
throw std::out_of_range("iterator error/n");
}

}

//*********************************************************
//这里采用两种方式来遍历树
//1:采用简单计数栈的非递归遍历(要求结点中有父节点数据域)
//2:采用栈的非递归遍历(在最后注释部分)
//*********************************************************

//前序遍历迭代器(无栈)

template <class Type>
class BinaryTree<Type>::PreOrder_iterator : public iterator {
using iterator::m_pCurrent;
using iterator::m_btree;
public:
PreOrder_iterator() {}
PreOrder_iterator(const BinaryTree<Type>& tree )
{
m_btree = const_cast< BinaryTree<Type>* >(&tree);
GotoFirst(); //索引至第一个结点
}

PreOrder_iterator(const PreOrder_iterator& iter) {
m_btree = iter.m_btree;
m_pCurrent = iter.m_pCurrent;
}

PreOrder_iterator& GotoFirst()
{
stk.MakeEmpty();
if(m_btree == NULL)
{
stk.MakeEmpty();
m_pCurrent = NULL;
}
else
{
m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot()); //强制转换为非常量指针
stk.Push(1); //记录当前树的根节点访问次数
}
return *this;
}

bool IsEnd()
{
return m_pCurrent == NULL;
}

PreOrder_iterator& operator++() ; // 游标自增
//PreOrder_iterator operator++(int);

private:
ChainStack<int> stk; //保存访问节点的遍历次数的栈
};

template <class Type>
typename BinaryTree<Type>::PreOrder_iterator&
BinaryTree<Type>::PreOrder_iterator::operator++() //前序后继节点
{
if( stk.IsEmpty() ) //确保迭代器是有效的
{
return *this;
}

//访问左子节点

if( m_pCurrent->GetLeft() == NULL) //左节点无效
{
stk.Pop();
stk.Push(2); //m_pCurrent 第二次访问

//查询右节点
if( m_pCurrent->GetRight() == NULL) //右节点也无效
{
//回溯搜索有效的节点
while( !stk.IsEmpty() && stk.Pop()==2 )
{
m_pCurrent = m_pCurrent->GetParent();
}

stk.Push(1);
//节点的右子节点不可访问,继续回溯,搜索到跟节点,停止搜索
while(m_pCurrent != NULL && m_pCurrent->GetRight() == NULL )
{
m_pCurrent = m_pCurrent->GetParent();
stk.Pop();
}

//如果已经搜索出根节点,抛出异常
if(m_pCurrent == NULL)
{
//throw std::out_of_range("BinaryTree iterator over/n");
}
else
{
stk.Pop();
stk.Push(2); //m_pCurrent访问计数2

m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);
}
}
else //右节点有效
{
m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);
}
}
else //左节点有效
{
m_pCurrent = m_pCurrent->GetLeft();
stk.Push(1);
}
return *this;
}

//中序遍历迭代器
//InOrder_iterator

template <class Type>
class BinaryTree<Type>::InOrder_iterator : public iterator {
using iterator::m_pCurrent;
using iterator::m_btree;
public:
InOrder_iterator() {}
InOrder_iterator(const BinaryTree<Type>& tree )
{
m_btree = const_cast< BinaryTree<Type>* >(&tree);
GotoFirst(); //索引至第一个结点
}

InOrder_iterator(const PreOrder_iterator& iter) {
m_btree = iter.m_btree;
m_pCurrent = iter.m_pCurrent;
}

InOrder_iterator& GotoFirst()
{
stk.MakeEmpty();
if(m_btree == NULL)
{
stk.MakeEmpty();
m_pCurrent = NULL;
}
else
{
m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot());
if( m_pCurrent != NULL )
{
stk.Push(1); //节点计数进1
while( m_pCurrent->GetLeft() != NULL )
{
m_pCurrent = m_pCurrent->GetLeft();
stk.Push(1);
}
}
}
return *this;
}

bool IsEnd()
{
return m_pCurrent == NULL;
}

InOrder_iterator& operator++() // 游标自增1
{
if(IsEnd())
{
return *this;
}

if( m_pCurrent->GetRight() == NULL)
{
stk.Pop();
stk.Push(2);
while( !stk.IsEmpty() && stk.Pop() == 2)
{
m_pCurrent = m_pCurrent->GetParent();
}
stk.Push(2);
return *this;
}
else
{
//右节点有效
stk.Pop();
stk.Push(2);
m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);

while( m_pCurrent->GetLeft() != NULL)
{
m_pCurrent = m_pCurrent->GetLeft();
stk.Push(1);
}
}
return *this;
}
//InOrder_iterator operator++(int);

private:
ChainStack<int> stk; //保存访问节点的遍历次数的栈

};

//**********************************************************
//后序遍历迭代器
//PostOrder_iterator
template <class Type>
class BinaryTree<Type>::PostOrder_iterator : public iterator {
using iterator::m_pCurrent;
using iterator::m_btree;
public:
PostOrder_iterator() {}
PostOrder_iterator(const BinaryTree<Type>& tree )
{
m_btree = const_cast< BinaryTree<Type>* >(&tree);
GotoFirst(); //索引至第一个结点
}

PostOrder_iterator(const PreOrder_iterator& iter) {
m_btree = iter.m_btree;
m_pCurrent = iter.m_pCurrent;
}

PostOrder_iterator& GotoFirst()
{
stk.MakeEmpty();
if(m_btree == NULL)
{
stk.MakeEmpty();
m_pCurrent = NULL;
}
else
{
m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot());
if( m_pCurrent != NULL )
{
stk.Push(1); //节点计数进1
while( m_pCurrent->GetLeft() != NULL || m_pCurrent->GetRight() != NULL)
{
if( m_pCurrent->GetLeft() != NULL)
{
m_pCurrent = m_pCurrent->GetLeft();
stk.Push(1);
}
else if( m_pCurrent->GetRight() != NULL)
{
stk.Pop();
stk.Push(2);
m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);
}
}
}
}
return *this;
}

bool IsEnd()
{
return m_pCurrent == NULL;
}

PostOrder_iterator& operator++() // 游标自增1
{
if(IsEnd())
{
return *this;
}

if( m_pCurrent->GetRight() == NULL || stk.GetTop() ==2)
{
m_pCurrent = m_pCurrent->GetParent();
stk.Pop();
}
if( m_pCurrent != NULL && m_pCurrent->GetRight() != NULL && stk.GetTop() ==1)
{
//父节点存在右节点,且并未访问过
stk.Pop();
stk.Push(2);
m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);
while( m_pCurrent->GetLeft() != NULL || m_pCurrent->GetRight() != NULL)
{
if( m_pCurrent->GetLeft() != NULL)
{
m_pCurrent = m_pCurrent->GetLeft();
stk.Push(1);
}
else if( m_pCurrent->GetRight() != NULL)
{
stk.Pop();
stk.Push(2);
m_pCurrent = m_pCurrent->GetRight();
stk.Push(1);
}
}
}
return *this;
}

private:
ChainStack<int> stk; //保存访问节点的遍历次数的栈
};

#endif /*BINARYTREE_H_*/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: