(C++)ios
實現的二叉樹類提供了以下功能express 1:由前序字串生成二叉樹安全 2:由後續字串生成二叉樹ide 3:提供三種迭代器,用於遍歷二叉樹函數 文件 test.cpp 是對二叉樹接口的測試,文件BinaryTree.h是二叉樹模板的實現,其中用到了鏈棧,myStack.h 在之前的文章提到過,而且也提供了代碼post
在BinaryTree.h 定義了幾個類學習 BinTreeNode :二叉樹節點類,帶父節點測試 BinaryTree : 二叉樹類this BinaryTree::iterator; //迭代器基類spa 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_*/ |