先序遍歷
void preOrder(TNode* root)
{
if ( root != NULL)
{
Stack S;
S.push(root);
while (!S.empty())
{
TNode* node = S.pop();
Visit(node); // 先訪問根節點,然後根節點就無需入棧了
if (node->right != NULL)
S.push(node->right); // 先push的是右節點,再是左節點
if (node->left != NULL)
S.push(node->left);
}
}
}
中序遍歷:原理就是先將最左邊的都壓棧,直到最左邊,然後出棧,出棧一個就訪問它的右子樹,這樣就能保證右子樹是在根節點訪問之後再訪問的,當然左子樹是最先訪問的
// 中序遍歷僞代碼:非遞歸版本,用棧實現
void InOrder(TNode* root)
{
Stack S;
while ( root != NULL || !S.empty() )
{
while( root != NULL ) // 左子樹入棧
{
S.push(root);
root = root->left;
}
if ( !S.empty() )
{
root = S.pop();
Visit(root->data); // 訪問根結點
root = root->right; // 通過下一次循環實現右子樹遍歷
}
}
}
後序遍歷
注意到,後序遍歷其實和前序遍歷很相似,前序遍歷順序爲 根節點->左子樹->右子樹,而後序遍歷順序爲 左子樹->右子樹->根結點,因此,我們只要保證根節點最後訪問即可,由於根節點是最先遍歷到的結點,而我們想讓他最後訪問,那麼這樣的做法就是將該根結點壓入另外一個棧,並且將右子樹和左子樹能夠分別壓入,然後,彈出該棧就能保證後序
可以用兩個輔助棧,一個棧用來遍歷,一個棧用來訪問
代碼如下
void postOrder(TNode *root)
{
if (root != NULL)
{
stack<TNode *> sTravel, sVisit;
sTravel.push(root);
while (!sTravel.empty())
{
TNode *p = sTravel.pop();
sVisit.push(p);
if (p->left != NULL) sVisit.push(p->left);
if (p->right != NULL) sVisit.push(p->right);
}
while (!sVisit.empty())
{
visit(sVisit.pop());
}
}
}