先定義結點的結構如下:
//二叉樹結點
typedef struct BiTNode{
//數據
char data;
//左右孩子指針
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreePtr;
後序遍歷最難,先搞後序遍歷。
遞歸:
//後序遍歷
void PostOrder(BiTreePtr T)
{
if(nullptr != T)
{
//訪問左子結點
PostOrder(T->lchild);
//訪問右子結點
PostOrder(T->rchild);
//訪問根節點
Visit(T);
}
}
迭代:
後序遍歷要求在遍歷完左右子樹後,再訪問根。需要判斷根結點的左右子樹是否均遍歷過。因爲相對於左右子結點來說,根結點總是被訪問。所以我們只需要額外再增加一個指針,指向剛剛訪問過的結點即可。只要剛剛訪問過的結點是當前結點的右結點,或者當前結點的右結點爲空,那麼就訪問當前結點。否則,去訪問當前結點的右子結點。
void PostOrder_iteration(BiTreePtr T) // 後序遍歷的非遞歸
{
std::stack<BiTreePtr> S;
BiTreePtr curr = T ; // 指向當前要檢查的節點
BiTreePtr previsited = nullptr; // 指向前一個被訪問的節點
while(nullptr != curr || !S.empty()) // 棧空時結束
{
while(nullptr != curr) // 一直向左走直到爲空
{
S.push(curr);
curr = curr->lchild;
}
curr = S.top();
// 當前節點的右孩子如果爲空或者已經被訪問,則訪問當前節點
if(nullptr == curr->rchild || curr->rchild == previsited)
{
cout<<curr->data<<" ";
previsited = curr;
S.pop();
curr = nullptr;
}
else
curr = curr->rchild; // 否則訪問右孩子
}
}
中序遍歷
遞歸:
//中序遍歷
void InOrder(BiTreePtr T){
if(nullptr != T !){
//訪問左子結點
InOrder(T->lchild);
//訪問根節點
Visit(T);
//訪問右子結點
InOrder(T->rchild);
}
}
迭代:
void InOrder_iteration(BiTreePtr T) // 中序遍歷的非遞歸
{
if(nullptr == T)
return ;
BiTreePtr curr = T; // 指向當前要檢查的節點
std::stack<BiTreePtr> s;
while(nullptr != curr || !s.empty())
{
while(nullptr != curr)
{
s.push(curr);
curr = curr->lchild;
}
curr = s.top();
s.pop();
cout<<curr->data<<" ";
curr = curr->rchild;
}
}
前序遍歷
遞歸:
//前序遍歷
void PreOrder(BiTNodePtr T)
{
if(nullptr == T)
return ;
printf("%c ", T->data); //輸出數據
PreOrder(T->lchild); //遞歸調用,前序遍歷左子樹
PreOrder(T->rchild); //遞歸調用,前序遍歷右子樹
}
迭代:
void PreOrder_iteration(BiTreePtr T) //先序遍歷的非遞歸
{
if(nullptr != T)
return ;
std::stack<BiTreePtr> s;
s.push(T);
while(!s.empty())
{
BiTree temp = s.top();
std::cout<<temp->data<<" ";
s.pop();
if(temp->rchild)
s.push(temp->rchild);
if(temp->lchild)
s.push(temp->lchild);
}
}
方法二,還是迭代:
void PreOrder_iteration(BiTreePtr T) //先序遍歷的非遞歸
{
if(nullptr != T)
return;
std::stack<BiTreePtr> s;
BiTreePtr curr = T;
while(nullptr != curr || !s.empty())
{
while(nullptr != curr)
{
std::cout<<curr->data<<" ";
s.push(curr);
curr = curr->lchild;
}
curr = s.top();
s.pop();
curr = curr->rchild;
}
}
最後,還有二叉樹的層次遍歷。對於層次遍歷,類似於圖的廣度優先DFS。這就該用隊列來實現了。
這篇博文寫的太長了,新開一篇來寫層次遍歷及相關變形吧。
http://blog.csdn.net/friendbkf/article/details/50316209