中序遍歷(遞歸+迭代)


題目要求

給定一個二叉樹,返回它的中序 遍歷。

示例
輸入: [1,null,2,3]
   1
    \
     2
    /
   3

輸出: [1,3,2]

進階: 遞歸算法很簡單,你可以通過迭代算法完成嗎?

解答:

迭代算法可用棧保存曾經路過的中序結點,回溯時可用bool型變量屏蔽對左子樹的訪問,避免發生死循環。

代碼及分析注釋如下:

#include<iostream>
#include<vector>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };
 
//中序遍歷遞歸算法
void inOrder(TreeNode* root, vector<int>& vi) {
    if (root != NULL) {
        inOrder(root->left, vi);
        vi.push_back(root->val);
        inOrder(root->right, vi);
    }
}
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> vi;
    inOrder(root, vi);
    return vi;
}

//中序遍歷迭代算法
vector<int> inOrderIteration(TreeNode* root) {
    vector<int> vi;
    vector<TreeNode *> stack;
    TreeNode* pT = root;
    bool backtrace = false;//回溯標志
    while (pT != NULL)
    {
        if (backtrace==false && pT->left != NULL)
        {//若存在左子樹,指針指向左子樹
            stack.push_back(pT);
            pT = pT->left;
        }else{//不存在左子樹,先保存當前值
            backtrace = false;//設置回溯標志為否
            vi.push_back(pT->val);
            if (pT->right != NULL) {//若存在右子樹,指針指向右子樹
                //stack.push_back(pT);-----------此時按理說應該不用入棧
                pT = pT->right;
            }else {//若不存在右子樹,返回父節點
                if (stack.empty() == false)
                {//若棧非空,取出棧頂元素
                    pT = stack.back();
                    stack.pop_back();
                    backtrace = true;//設定回溯標記為true,這樣便能不再訪問左子樹
                }
                else//需要回溯,但棧已空,此時遍歷已結束
                    break;
            }
        }
    }
    return vi;
}

int main()
{
    TreeNode a(1), b(2), c(3), d(4), e(5), f(6), g(7), h(8), i(9), j(10);
    a.left = &b;
    a.right = &e;
    b.left = &c;
    b.right = &d;
    d.right = &f;
    e.left = &g;
    e.right = &h;
    h.left = &i;
    i.right = &j;
//    auto vi = inorderTraversal(&a);
    auto vi = inOrderIteration(&a);
    for (auto i = vi.begin(); i != vi.end(); ++i)
    {
        cout << *i << "\t";
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM