1. 程式人生 > >二叉樹完整實現C++

二叉樹完整實現C++

總結網上一位大牛寫的程式碼,看看人家,就寫一個二叉樹,就把C++繼承多型的作用發揮出來,看咱只能簡單定義一個class, 差距大啊~自己還是小白~

BinaryTree.h
#ifndef BINARY_TREE
#define BINARY_TREE


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

using namespace std;

enum ChildID{LEFTCHILD = 0, RIGHTCHILD};//子節點型別,左節點or右節點;

template<class T> class BinaryTree;

template<class T> class BTreeNode
{
	friend class BinaryTree<T>;
public:
	BTreeNode(): pParent(0), pLChild(0), pRChild(0){}
	BTreeNode(T elem, BTreeNode<T>* parent=0, BTreeNode* lchild=0, BTreeNode* rchild=0):
		pParent(parent),pLChild(lchild),pRChild(rchild),data(elem) {}
	
	T GetData() const; //獲取節點資料;
	T& GetDataRef();         //不應當提供這樣的介面,這裡僅僅讓iterator能夠自由訪問儲存的資料;
	BTreeNode* GetParent() const;//獲取節點的父節點
	BTreeNode* GetLChild() const;//獲取節點的左孩子節點
	BTreeNode* GetRChild() const;//獲取節點的右孩子節點
	void SetData(const T& elem );//修改節點的資料;
	
	/*下面是更改節點的指標域結構的function,是否真的需要,還得仔細考量
	做為樹的節點,一般不允許直接訪問節點中的指標資料,如果這些資料在樹
	被建立完成以後修改,會破壞樹的結構;*/
	void SetParent( BTreeNode<T>* parent, ChildID CHID ); //設定當前節點的父節點,並指定當前節點作為子節點的型別;
	void SetLeft( BTreeNode<T>* left);                 //設定當前節點的左子節點;
	void SetRight( BTreeNode<T>* right);               //設定當前節點的右子節點;


private:
	BTreeNode<T>* pParent;
	BTreeNode<T>* pLChild;
	BTreeNode<T>* pRChild;
	T data;
};
//declare BTreeNode end

//*********************************************************
// BTreeNode Implementation
//*********************************************************

template<class T> T BTreeNode<T>::GetData() const
{ return data;}

template<class T>T& BTreeNode<T>::GetDataRef()
{ return data;}

template<class T>T BTreeNode<T>::GetParent() const
{ return pParent;}

template<class T>T BTreeNode<T>::GetRChild() const
{ return pRChild;}

template<class T>T BTreeNode<T>::GetLChild() const
{ return pLChild;}

template<class T>T BTreeNode<T>::SetData(const T& elem)
{ data = elem;}

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

	if(CHID==LEFTCHILD) //當前節點作為parent的左子節點;
	{
		pParent = parent;
		parent->pLChild = this;
	}
	else if (CHID==RIGHTCHILD)
	{
		pParent = parent;
		parent->rLChild = this;
	}
}

template<class T>void BTreeNode<T>::SetLeft(BTreeNode<T>* left)
{ pLChild=left; }
template<class T>void BTreeNode<T>::SetRight(BTreeNode<T>* right)
{ pRChild=right; }

// BTreeNode Implementation over
//*********************************************************
//*********************************************************

template<class T> class BinaryTree
{
public:
	BinaryTree() : root(NULL){}
	BinaryTree( T value) : RefValue(value), root(NULL) {}
	BinaryTree( const BinaryTree<T>& tree);                 //copy ConstruBcture privated
	BinaryTree<T>& operator=(const BinaryTree<T>& tree); //operator= privated

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

	/*
    * 下面三個函式的可用性,返回值型別的正確性值得考量
    * 這樣做不僅會破壞樹的結構,而且很容易引起記憶體洩漏
    * 在一般的樹中最好不要提供這三個介面 ;
    */
	virtual BTreeNode<T>* Parent( BTreeNode<T>* current ); //返回所給結點父結點;
	virtual BTreeNode<T>* LeftChild( BTreeNode<T>* current);      //返回節點的左孩子;
	virtual BTreeNode<Ty>* RightChild( BTreeNode<T>* current);     //返回節點的右孩子;

	virtual bool Insert( const T& item);        //插入元素;
	virtual bool Find( const T& item) const;    //搜尋元素;
	const BTreeNode<T>* GetRoot() const;      //取樹根;

	//遍歷操作
	void PreOrder() const;   //前序;
	void InOrder() const; //中序;
	void PostOrder() const;  //後序;

	//二叉樹特性操作函式
	int Size() const;
	int Size( const BTreeNode<T>* troot) const;
	int Height() const;
	int Height( const BTreeNode<T>* troot) const;
	bool operator==( const BinaryTree<T>& tree) const;

	//下面的介面是以不同的方式來構建二叉樹
	BinaryTree<T>& AutoCreateTree(const std::string& expstr);            //自動判斷格式並建立
	BinaryTree<T>& PreOrderCreateTree(const std::string& expstr);        //先序建立
	BinaryTree<T>& PostOrderCreateTree(const std::string& expstr);       //後續建立

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

	//遍歷遞迴
	void InOrder( BTreeNode<T>* current) const;
	void PreOrder( BTreeNode<T>* current ) const;
	void PostOrder( BTreeNode<T>* current) const;

	//二叉樹特性遞迴操作函式
	BTreeNode<T>* Copy( BTreeNode<T>* troot, BTreeNode<T>* parent);
	bool equal( BTreeNode<T>* troot1, BTreeNode<T>* troot2) const;


	//建樹用的遞迴函式
	BTreeNode<T>* PreOrderCreateNode(const char* &expstr, BTreeNode<T>* parent);    //先序遞迴建立二叉樹
	BTreeNode<T>* PostOrderCreateNode(const char* &expstr, BTreeNode<T>* 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:
	BTreeNode< T >* root;     //樹的根指標  
	T RefValue;              //資料輸入終結標誌

};
//END BinaryTree
/**********************************
 * implament of template BinaryTree 
 * 
 **********************************/
template <class T> 
BinaryTree<T>::BinaryTree( const BinaryTree<T>& tree)   //copy Constructor
{
	root = Copy(tree.root, NULL);
}

template <class T> BinaryTree<T>& BinaryTree<T>::operator=( const BinaryTree<T>& tree)     //operator= constructor
{
	destroy(root);
	root = Copy(tree.root, NULL);
	return *this;
}
template <class T> BinaryTree<T>::~BinaryTree()
{
	destroy(root);              //遍歷刪除二叉樹
}

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

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

template <class T>BTreeNode<T>* BinaryTree<T>::Parent( BTreeNode<T>* current)
{
	if( root == NULL || root == current )
	{
		return NULL;
	}
	else
	{
		return current->pParent;
	}
	/*
    * 由於節點保留了parent的地址,所以可以直接取得父節點的地址
    * 但是節點中如果沒有parent的資料,就必須呼叫遞迴查詢來尋找父節點的地址
    * 程式碼片斷如下,它呼叫了Parent( BTreeNode<T> *start, BTreeNode<T>* current)
 
     return (root == NULL || root == current) ? NULL : Parent( root, current);
     
     */   
}

template <class T>BTreeNode<T>* BinaryTree<T>::LeftChild( BTreeNode<T>* current)
{
	return current != NULL ? current->pLChild : NULL;
}

template <class T>BTreeNode<T>* BinaryTree<T>::RightChild( BTreeNode<T>* current)
{
	return current != NULL ? current->pRChild : NULL;  
}

template <class T>BTreeNode<T>* BinaryTree<T>::Parent( BTreeNode<T> *start, BTreeNode<T>* current)
{
	//從結點start開始,搜尋節點current的父結點,
	//如果找到其父節點,則函式將其返回,否則返回 NULL
	if( !start ) return NULL;
	if( start->pLChild == current || start->pRChild == current) 
		return start;

	BTreeNode<T> *pNode;
	if((pNode = Parent( start->pLChild, current)) != NULL) 
	{
		return pNode;      
	}                                 
	else 
	{
		return Parent( start->pRChild, current);  
	}                              
}

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

template <class T>
void BinaryTree<T>::Travers( BTreeNode<T>* current, std::ostream& out) const 
{
	//前序輸出根為current的二叉數
	if( current ) {
		out << current->data;
		Travers( current->pLChild , out );
		Travers( current->pRChild, out );
	}
	else
	{
		out<<"#";
	}
}
//中序遍歷操作
template <class T>
void BinaryTree<T>::InOrder() const 
{
	std::cout << "InOrder Traval Tree:/n";
	InOrder( root );
	std::cout << std::endl;     
}

template <class T>
void BinaryTree<T>::InOrder( BTreeNode<T>* current) const
{
	//遞迴私有函式,中序遍歷二叉樹
	if(current != NULL) {
		InOrder(current->pLChild);
		std::cout << current->data;     
		InOrder(current->pRChild);   
	}  
	else 
	{
		std::cout << "#";
	}
}

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

template <class T>
void BinaryTree<T>::PreOrder( BTreeNode<T>* current) const
{
	if(current != NULL) {
		std::cout << current->data;
		PreOrder(current->pLChild);
		PreOrder(current->pRChild);
	}
	else
	{
		std::cout <<"#";
	}
}

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

template <class T>
void BinaryTree<T>::PostOrder( BTreeNode<T>* current) const{
	//後序遞迴操作

	if( current != NULL ) {
		PostOrder(current->pLChild);
		PostOrder(current->pRChild);
		std::cout << current->data;
	}
	else
	{
		std::cout << "#";
	}
}
//計算二叉樹的結點數
template <class T>
int BinaryTree<T>::Size() const 
{
   return Size(root);
}
 
template <class T>
int BinaryTree<T>::Size( const BTreeNode<T>* troot) const 
{
   if(troot == NULL)  return 0;   //空樹,返回0
   else return 1 + Size(troot->pLChild) + Size(troot->pRChild);
   
}
 
//計算二叉樹的高度
template <class T>
int BinaryTree<T>::Height() const
{
   return Height(root);
}
 
template <class T>
int BinaryTree<T>::Height( const BTreeNode<T>* troot) const 
{
   if ( troot == NULL ) return -1;
   else return 1 + MAX( Height( troot->pLChild ) , Height( troot->pRChild) );
}
 
//遞迴拷貝的私有函式;
template <class T>
BTreeNode<T>* BinaryTree<T>::Copy( BTreeNode<T>* troot, BTreeNode<T>* parent) 
{
   if (NULL == troot) return NULL;   
   BTreeNode<T>* pNode = new BTreeNode<T>;
   pNode->data = troot->data;                          //拷貝資料
   pNode->pParent = parent;
   pNode->pLChild = Copy( troot->pLChild, pNode );        //新建左子樹
   pNode->pRChild = Copy( troot->pRChild, pNode );        //新建右子樹
   return pNode;                                     //返回樹根結點
}
 
//判斷二叉樹內容是否相等
template <class T>
bool BinaryTree<T>::operator==( const BinaryTree<T>& tree) const 
{
   return equal( root, tree.root );
}
 
//判斷二叉樹相等的遞迴操作
template <class T>
bool BinaryTree<T>::equal( BTreeNode<T>* troot1, BTreeNode<T>* 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->pLChild, troot2->pLChild) &&   equal( troot1->pRChild, troot2->pRChild);
   }
   return true;
}
 
template <class T> 
void BinaryTree<T>::destroy( BTreeNode<T>* current) {
   if( current ) {
      destroy( current->pLChild );    //遞迴刪除左結點
      destroy( current->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 T>
BinaryTree<T>& 
BinaryTree<T>::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 T>
BTreeNode<T>*
BinaryTree<T>::PreOrderCreateNode(const char* &expstr, BTreeNode<T>* parent)
{
   if( *expstr == '#' || *expstr == '/0') return NULL;
   BTreeNode<T>* pnewNode = new BTreeNode<T>(*expstr, parent);
   
   assert(pnewNode);
   
   pnewNode->pLChild = PreOrderCreateNode(++expstr, pnewNode);
   pnewNode->pRChild = PreOrderCreateNode(++expstr, pnewNode);
   return pnewNode;
}
 
//*********************************************************
 
//*********************************************************
 
//3:後續方式建立二叉樹
template <class T>
BinaryTree<T>& 
BinaryTree<T>::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 T>
BTreeNode<T>*
BinaryTree<T>::PostOrderCreateNode(const char* &expstr, BTreeNode<T>* parent)
{
   if( *expstr == '#') return NULL;
   BTreeNode<T>* pnewNode = new BTreeNode<T>(*expstr, parent);
   
   assert(pnewNode);
   pnewNode->pRChild = PostOrderCreateNode(--expstr, pnewNode);
   
   pnewNode->pLChild = PostOrderCreateNode(--expstr, pnewNode);
   
   return pnewNode;
}
 
 //********************************************************
//********************************************************
//三種迭代器的實現
 
//iterator 是私有的基類迭代器,這裡沒有實現常量樹的迭代器 const_iterator
//這樣做確保了使用者不可能訪問到這個迭代器
template <class T>
class BinaryTree<T>::iterator {
public:
   iterator():m_btree(NULL), pCurrent(NULL){}
   virtual ~iterator() {}
   
   virtual iterator& operator= (const iterator& iter) 
   { 
      pCurrent = iter.pCurrent;
      return *this;
   }
   
   virtual iterator& GotoFirst() = 0;      //遊標索引到第一個節點
   virtual bool IsEnd() = 0;               //遊標是否已經索引到末尾
   
   virtual iterator& operator++() = 0;         // 遊標自增
   //virtual iterator operator++(int) = 0;
   
   virtual const T& current() const;
   virtual T& operator*();
   virtual T* operator->();
protected:
   BinaryTree<T>* m_btree;
   BTreeNode<T>* pCurrent; 
};
 
template <class T>
const T& 
BinaryTree<T>::iterator::current() const 
{
   if(pCurrent != NULL)
   {
      return pCurrent->GetDataRef();
   }
   else
   {
      throw std::out_of_range("iterator error/n");
   }
}
 
template <class T>
T& 
BinaryTree<T>::iterator::operator*()
{
   if(pCurrent != NULL)
   {
      return pCurrent->GetDataRef();
   }
   else
   {
      throw std::out_of_range("iterator error/n");
   }  
}
 
template <class T>
T* 
BinaryTree<T>::iterator::operator->()
{
   if(pCurrent != NULL)
   {
      return &(pCurrent->GetDataRef());
   }
   else
   {
      throw std::out_of_range("iterator error/n");
   }     
   
}
 
//*********************************************************
//這裡採用兩種方式來遍歷樹
//1:採用簡單計數棧的非遞迴遍歷(要求結點中有父節點資料域)
//2:採用棧的非遞迴遍歷(在最後註釋部分)
//*********************************************************
 
 
//前序遍歷迭代器(無棧)
 
template <class T>
class BinaryTree<T>::PreOrder_iterator : public iterator {
   using iterator::pCurrent;
   using iterator::m_btree;
public:
   PreOrder_iterator() {}
   PreOrder_iterator(const BinaryTree<T>& tree )
   {
      m_btree = const_cast< BinaryTree<T>* >(&tree);
      GotoFirst();	//索引至第一個結點;  
   }
   
   PreOrder_iterator(const PreOrder_iterator& iter) {
      m_btree = iter.m_btree;
      pCurrent = iter.pCurrent;
   }
   
   PreOrder_iterator& GotoFirst()
   {
      stk.MakeEmpty();
      if(m_btree == NULL)
      {
         stk.MakeEmpty();
         pCurrent = NULL;
      }
      else
      {
         pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot());  //強制轉換為非常量指標
         stk.Push(1);    //記錄當前樹的根節點訪問次數
      }
   return *this;
   }
   
   bool IsEnd() 
   {
      return pCurrent == NULL;  
   }
   
   PreOrder_iterator& operator++() ;           // 遊標自增;
   //PreOrder_iterator operator++(int);
   
private:
   stack<int> stk;        //儲存訪問節點的遍歷次數的棧;
};
 
template <class T>
 BinaryTree<T>::PreOrder_iterator&  
BinaryTree<T>::PreOrder_iterator::operator++() //前序後繼節點;
{
   if( stk.IsEmpty() )      //確保迭代器是有效的;
   {
      return *this;
   }
   
   //訪問左子節點
 
   if( pCurrent->GetLeft() == NULL) //左節點無效;
   {
      stk.Pop();
      stk.Push(2); //pCurrent 第二次訪問;
      
      //查詢右節點;
      if( pCurrent->GetRight() == NULL)  //右節點也無效;
      {
         //回溯搜尋有效的節點
         while( !stk.IsEmpty() && stk.Pop()==2 ) 
         {
            pCurrent = pCurrent->GetParent();
         }
         
         stk.Push(1);
         //節點的右子節點不可訪問,繼續回溯,搜尋到跟節點,停止搜尋;
         while(pCurrent != NULL && pCurrent->GetRight() == NULL )
         {
            pCurrent = pCurrent->GetParent();
            stk.Pop();
         }
         
         //如果已經搜尋出根節點,丟擲異常;
         if(pCurrent == NULL)
         {
            //throw std::out_of_range("BinaryTree iterator over/n");
         }
         else 
         {
            stk.Pop();
            stk.Push(2); //pCurrent訪問計數2;
            
            pCurrent = pCurrent->GetRight();
            stk.Push(1); 
         }
      }
      else //右節點有效
      {
         pCurrent = pCurrent->GetRight();
         stk.Push(1);
      }
   }
   else  //左節點有效
   {
      pCurrent = pCurrent->GetLeft();  
      stk.Push(1);
   }
   return *this;
}
 
 
//中序遍歷迭代器
//InOrder_iterator
 
 
template <class T>
class BinaryTree<T>::InOrder_iterator : public iterator {
   using iterator::pCurrent;
   using iterator::m_btree;
public:
   InOrder_iterator() {}
   InOrder_iterator(const BinaryTree<T>& tree )
   {
      m_btree = const_cast< BinaryTree<T>* >(&tree);
      GotoFirst(); //索引至第一個結點   
   }
   
   InOrder_iterator(const PreOrder_iterator& iter) {
      m_btree = iter.m_btree;
      pCurrent = iter.pCurrent;
   }
   
   InOrder_iterator& GotoFirst()
   {
      stk.MakeEmpty();
      if(m_btree == NULL)
      {
         stk.MakeEmpty();
         pCurrent = NULL;
      }
      else
      {
         pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot());
         if( pCurrent != NULL )
         {
            stk.Push(1); //節點計數進1
            while( pCurrent->GetLeft() != NULL )
            {
               pCurrent = pCurrent->GetLeft();
                stk.Push(1);             
            }           
         }
      }
      return *this;
   }
   
   
   bool IsEnd() 
   {
      return pCurrent == NULL;  
   }
   
   InOrder_iterator& operator++()           // 遊標自增1
   {
      if(IsEnd()) 
      {
         return *this;   
      }
      
      if( pCurrent->GetRight() == NULL)
      {
         stk.Pop();
         stk.Push(2);
         while( !stk.IsEmpty() && stk.Pop() == 2)
         {
            pCurrent = pCurrent->GetParent();          
         }
         stk.Push(2);
         return *this;
      }
      else
      {
         //右節點有效
         stk.Pop();
         stk.Push(2);
         pCurrent = pCurrent->GetRight();
         stk.Push(1);
         
         while( pCurrent->GetLeft() != NULL)
         {
            pCurrent = pCurrent->GetLeft();
            stk.Push(1);          
         }
      }
      return *this;      
   }
   //InOrder_iterator operator++(int);
   
private:
   ChainStack<int> stk;        //儲存訪問節點的遍歷次數的棧
 
};
 
 
//**********************************************************
//後序遍歷迭代器
//PostOrder_iterator
template <class T>
class BinaryTree<T>::PostOrder_iterator : public iterator {
   using iterator::pCurrent;
   using iterator::m_btree;
public:
   PostOrder_iterator() {}
   PostOrder_iterator(const BinaryTree<T>& tree )
   {
      m_btree = const_cast< BinaryTree<T>* >(&tree);
      GotoFirst(); //索引至第一個結點   
   }
   
   PostOrder_iterator(const PreOrder_iterator& iter) {
      m_btree = iter.m_btree;
      pCurrent = iter.pCurrent;
   }
   
   PostOrder_iterator& GotoFirst()
   {
      stk.MakeEmpty();
      if(m_btree == NULL)
      {
         stk.MakeEmpty();
         pCurrent = NULL;
      }
      else
      {
         pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot());
         if( pCurrent != NULL )
         {
            stk.Push(1); //節點計數進1
            while( pCurrent->GetLeft() != NULL || pCurrent->GetRight() != NULL)
            {
                if( pCurrent->GetLeft() != NULL) 
                {
                   pCurrent = pCurrent->GetLeft();
                   stk.Push(1); 
                }
                else if( pCurrent->GetRight() != NULL)
                {
                   stk.Pop();
                   stk.Push(2);
                   pCurrent = pCurrent->GetRight();
                   stk.Push(1);
                }        
            }           
         }
      }
      return *this;
   }
   
   bool IsEnd() 
   {
      return pCurrent == NULL;  
   }
   
   PostOrder_iterator& operator++()            // 遊標自增1
   {
      if(IsEnd()) 
      {
         return *this;   
      }
      
      if( pCurrent->GetRight() == NULL || stk.GetTop() ==2)
      {
         pCurrent = pCurrent->GetParent();
         stk.Pop();
      }
      if( pCurrent != NULL && pCurrent->GetRight() != NULL && stk.GetTop() ==1)   
      {
         //父節點存在右節點,且並未訪問過
         stk.Pop();
         stk.Push(2);
         pCurrent =  pCurrent->GetRight();
         stk.Push(1);
         while( pCurrent->GetLeft() != NULL || pCurrent->GetRight() != NULL)
         {
            if( pCurrent->GetLeft() != NULL) 
            {
                pCurrent = pCurrent->GetLeft();
                stk.Push(1); 
            }
            else if( pCurrent->GetRight() != NULL)
            {
                stk.Pop();
                stk.Push(2);
                pCurrent = pCurrent->GetRight();
                stk.Push(1);
            }
         }
      }
      return *this;      
   }
   
private:
   ChainStack<int> stk;        //儲存訪問節點的遍歷次數的棧
};

#endif
BinaryTree.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;
}

相關推薦

完整實現C++

總結網上一位大牛寫的程式碼,看看人家,就寫一個二叉樹,就把C++繼承多型的作用發揮出來,看咱只能簡單定義一個class, 差距大啊~自己還是小白~ BinaryTree.h#ifndef BINARY_TREE #define BINARY_TREE #include

實現c++)

二叉樹的實現(c++) BinNode.h(節點的實現實現) template <typename E> class BinNode { public: virtual ~BinNode() {}; virtual E& element() = 0; vir

C++ 實現、基本操作以及指標使用注意事項(轉自部落格)

內容: 模板實現簡單的二叉樹 二叉樹的前序,中序,後序遍歷 統計二叉樹結點的個數和深度 二叉樹的銷燬操作   具體的實現過程及注意事項見程式碼部分;   #include <iostream&

C語言線索實現

        線索二叉樹的主要操作,包含:以p為根節點的子樹中序線索化,帶頭結點的二叉樹中序線索化和遍歷線索二叉樹這幾個函式。         下面講一下實現程式碼:                    首先,依然是型別定義,並宣告一個全域性變數pre: typed

線索實現C語言)

概念 鑑於普通二叉樹使用過程中會出現空間的浪費,後人對在在二叉樹的的基礎上做了改進,利用它的空指標域存放在某種遍歷次序下指向它的前驅結點,和後繼結點的指標。這些指標稱為線索,相應的二叉樹就成了線索二叉樹。 結點結構 Ltag為0時指向該結點的左孩子,

演算法的樂趣c/c++ —— 2.2 實現

宣告:參考書籍《演算法筆記》 作者:作者: 胡凡 / 曾磊  出版社: 機械工業出版社   ISBN: 9787111540090 二叉樹其實是特殊的連結串列,是每個節點有一個數據域,兩個指標。而連結串列只有一個數據,一個指標。關於二叉樹可以參考博文二叉樹就是這麼簡單。我們現

遍歷c++實現

//自己還真是個菜雞,大一學了一年c++,現在還在基礎的語法上轉圈,還沒有意識到c++真正的 //的強大之處在於它的多變,封裝,等演算法告一段落了在考慮是往Java上走還是深造c++ #include <iostream> #include <stack&

[leetcode]Same Tree(判斷兩個是否相等 C語言實現)

Same Tree Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if th

資料結構之 AVL(平衡)(C語言實現

AVL樹(平衡二叉樹) 1. AVL樹定義和性質 AVL(Adelson-Velskii和Landis發明者的首字母)樹時帶有平衡條件的二叉查詢樹。 二叉查詢樹的效能分析: 在一顆左右子樹高度平衡情況下,最優的時間複雜度為O(log2n),這與這半

的操作--C語言實現

div break 叠代 二叉樹 node 若是 postorder 元素 初始化 樹是一種比較復雜的數據結構,它的操作也比較多。常用的有二叉樹的創建,遍歷,線索化,線索化二叉樹的遍歷,這些操作又可以分為前序,中序和後序。其中,二叉樹的操作有遞歸與叠代兩種方式,鑒於我個人的

實現與操作(C語言實現)

 二叉樹的定義:     上一篇的樹的通用表示法太過於複雜,由此這裡採用了孩子兄弟表示法來構建二叉樹。 孩子兄弟表示法: 每個結點包含一個數據指標和兩個結點指標 --->資料指標:指向保存於樹中的資料 --->孩子結點指標:指向第一個孩子 --->兄

C++資料結構之 --簡單實現和4種遍歷

實驗目的:實現簡單的二叉樹! 標頭檔案: 二叉樹.h #ifndef 二叉樹_h__ #define 二叉樹_h__ #include <iostream> #include <q

C語言實現

        二叉樹的儲存結構包含順序儲存結構和鏈式儲存結構,由於順序儲存結構很容易造成不必要的浪費,本人用的是鏈式儲存結構(注意在實際操作中最後 要釋放節點空間)。基本操作包括:遍歷二叉樹、先序遍歷的順序建立二叉樹、複製二叉樹、計算二叉樹深度、計算二叉樹結點個數。下面講

遍歷-c實現

bin lib malloc code mage -a oid inf 樹遍歷 這裏主要是三種遍歷,先序(preorder,NLR),中序(Inorder,LNR),後序(Postorder,LRN) N:node,L:left,R:right 基本排序:先序(NLR,

遍歷 C#

這就是 中序 工作 class stat public 完全 每一個 前期準備 二叉樹遍歷 C# 什麽是二叉樹   二叉樹是每個節點最多有兩個子樹的樹結構  (1)完全二叉樹——若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結

及其實現(基礎版)

除了 一覽 display ros return 路徑 動態操作 spl signature 前言:常見的數據結構都有指針和數組兩種實現方式,這篇先介紹指針實現,而數組實現在後續文章裏會講到。 (長文預警!) 說完了一般的樹,我們再來看看二叉樹,這是一種很典

輸入某的前序遍歷和中序遍歷的結果,請重建出該(java實現並測試)

假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。 package ssp; class TreeNode { int val; TreeNod

14_資料結構與演算法__Python實現

#Created By: Chen Da class BinaryTree(object): def __init__(self,rootObj): self.key = rootObj self.left_child = None sel

(0)——實現的遍歷

0.二叉樹的實現(C++) 未完,待補充 #include <iostream> #include<iostream> #include<queue> #include<stack> using namespace std; //二叉樹結點的

基本實現(包含main方法)

所用編譯器;Devc++(有些編譯器編譯不了,建議使用Devc++) 所用語言:C語言 邏輯結構:非線性結構 儲存結構:鏈式儲存結構 寫在前面:學習二叉樹之前也有找過一些學習資料,資料結構的書,部落格文章,但是都大概講述的是方法,並沒有給出完整的且比較適合初學者的,今天剛剛學習了二叉