二叉樹是數據結構中的經典結構,也是應用很廣泛的結構之一。二叉樹具有一些特定的性質,如 n0 = n2+1,在一些應用中,常常要求在樹中查找具有某些特徵的節點,或者對樹中節點進行處理,即遍歷二叉樹的問題,其遞歸算法非常容易實現,非遞歸算法也有兩種思路,本文將在程序中實現筆者認爲容易識記的一種方法。
輸入序列二叉樹:
程序實現:
#include <iostream>
#include <stack>
using std::cin;
using std::cout;
using std::endl;
using std::stack;
// 定義二叉樹結構, BiTree 爲指針類型
typedef struct BiTreeNode{
int data;
struct BiTreeNode *lchild,*rchild;
}BiTreeNode,*BiTree;
// &T 必須,可以試試去掉的後果
// 輸入爲先序序列的順序,如圖 輸入序列爲: 1 2 0 0 3 4 6 0 0 7 0 0 5 0 8 0 0
// 0 - 表示 NULL,這裏爲了測試而設置的
BiTree fn_CreateBiTree(BiTree &T)
{
int data;
cin>>data;
if(data==0)T=NULL; // 遇到值爲0的,將其置爲NULL,表示爲空
else{
if(!(T = (BiTree)new BiTreeNode))exit(0);
T->data=data;
fn_CreateBiTree(T->lchild);
fn_CreateBiTree(T->rchild);
}
return(T);
}
// 先序遍歷 遞歸實現
void fn_PreOrderTraverse(BiTree T)
{
if(T)
{
if(T->data)
{
cout<<T->data<<'\t';
fn_PreOrderTraverse(T->lchild);
fn_PreOrderTraverse(T->rchild);
}
return;
}
else
return;
}
// 中序遍歷 遞歸實現
void fn_MidOrderTraverse(BiTree T)
{
if(T)
{
if(T->data)
{
fn_MidOrderTraverse(T->lchild);
cout<<T->data<<'\t';
fn_MidOrderTraverse(T->rchild);
}
return;
}
else
return;
}
// 中序遍歷 非遞歸
void InOrderTraverse(BiTree T)
{
stack<BiTree> NodeStack; // 需要用到棧
BiTree p; // 遍歷的指針變量,類似於遊標功能
if(T) // 非空二叉樹
{
p = T;
while(p || !NodeStack.empty()) // 若p不爲空,或者棧非空,則進入循環
{ // 初始p非空,棧爲空
if(p)
{
NodeStack.push(p); // 將非空節點入棧,向左孩子遍歷
p=p->lchild;
}
else // 此時p爲空,則p的父節點爲棧頂指針,爲分支最左的孩子,輸出
{
p = NodeStack.top(); // 將p賦值爲棧頂指針
cout<<p->data<<'\t'; // 輸出分支最左孩子
NodeStack.pop(); // 刪除棧頂指針
p = p->rchild; // 將p賦值給其右孩子,繼續遍歷其右孩子分支
}
}
}
else
return;
}
void main(void)
{
BiTree T;
cout<<"輸入二叉樹序列,創建二叉樹:"<<endl;
T = fn_CreateBiTree(T);
cout<<endl;
cout<<"輸出先序遍歷-遞歸算法:"<<endl;
fn_PreOrderTraverse(T);
cout<<endl;
cout<<"輸出中序遍歷-遞歸算法:"<<endl;
fn_MidOrderTraverse(T);
cout<<endl;
cout<<"輸出中序遍歷-非遞歸算法:"<<endl;
InOrderTraverse(T);
cout<<endl;
}
程序運行結果: