NC45 实现二叉树先序,中序和后序遍历
题意分析:
实现二叉树的先序,中序,后续遍历
题解一(递归遍历):
比如有二叉树
 
先序遍历:按照访问树根,左子树,右子树的顺序对树进行遍历,子树同样遵守这个遍历顺序
如图所示的二叉树:先序遍历结果为4,2,1,3,5.
代码实现如下:
void preOrder(TreeNode *root, vector<int> &ret) {
    if (!root) {
        return;
    }
    ret.push_back(root->val);
    preOrder(root->left, ret);
    preOrder(root->right, ret);
} 中序遍历:按照访问左子树,树根,右子树的顺序对树进行遍历,子树同样遵守这个遍历顺序
如图所示的二叉树:中序遍历结果为1,2,3,4,5.
代码实现如下:
void inOrder(TreeNode *root, vector<int> &ret) {
    if (!root) {
        return;
    }
    inOrder(root->left, ret);
    ret.push_back(root->val);
    inOrder(root->right, ret);
} 后序遍历:按照访问左子树,右子树,树根的顺序对树进行遍历,子树同样遵守这个遍历顺序
如图所示的二叉树:后序遍历结果为1,3,2,5,4.
代码实现如下:
void posOrder(TreeNode *root, vector<int> &ret) {
    if (!root) {
        return;
    }
    posOrder(root->left, ret);
    posOrder(root->right, ret);
    ret.push_back(root->val);
} 总结:那种遍历就表示什么时候访问根结点,先序表示首先访问根结点。中序表示在中间访问根结点
后序表示最后访问根节点。
三种遍历算法时间复杂度,n为树中结点个数。
空间复杂度:,h为树深。
题解二:(将递归用栈模拟):
递归调用本质上都可以用栈进行模拟。
先序遍历的非递归展开:
vector<int> PreOrderNonRecur(TreeNode *root) {
    TreeNode *T = root;
    stack<TreeNode *> S;
    vector<int> ret;
    while (T || !S.empty()) {
        while (T) {
            ret.push_back(T->val);
            S.push(T);
            T = T->left;
        }
        if (!S.empty()) {
            T = S.top();
            S.pop();
            T = T->right;
        }
    }
    return ret;
} 中序遍历的非递归展开:
vector<int> inOrderNonRecur(TreeNode *root) {
    TreeNode *T = root;
    stack<TreeNode *> S;
    vector<int> ret;
    while (T || !S.empty()) {
        while (T) {
            S.push(T);
            T = T->left;
        }
        if (!S.empty()) {
            T = S.top();
            S.pop();
            ret.push_back(T->val);
            T = T->right;
        }
    }
    return ret;
} 后序遍历的非递归展开:
后序遍历有点特殊,其访问顺序为左子树-右子树-根,可以利用栈,依次将根-右子树-左子树压栈,在弹出的时候就有这个顺序。先序遍历的顺序为根-左子树-右子树,只要将先序遍历的非递归展开左右先后顺序,最后输出栈中的元素即可。
vector<int> posOrderNonRecur(TreeNode *root) {
    TreeNode *T = root;
    stack<TreeNode *> S1;
    stack<TreeNode *> S2;
    while (T || !S1.empty()) {
        while (T) {
            S2.push(T);
            S1.push(T);
            T = T->right;
        }
        if (!S1.empty()) {
            T = S1.top();
            S1.pop();
            T = T->left;
        }
    }
    vector<int> ret;
    while (!S2.empty()) {
        ret.push_back(S2.top()->val);
        S2.pop();
    }
    return ret;
} 三种遍历算法时间复杂度,n为树中结点个数。
空间复杂度:,h为树深。

 京公网安备 11010502036488号
京公网安备 11010502036488号