非遞歸先序中序後序遍歷二叉樹

先序遍歷

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());
    }
  }
}





發佈了140 篇原創文章 · 獲贊 70 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章