Binary Tree Traversal (一)

Binary Tree Traversal

Binary Tree Traversal
leetcode上有对应的题目
题目描述:
二叉树的遍历,先序、中序、后序的递归和非递归实现。
二叉树的深度优先遍历、广度优先遍历。

二叉树的递归实现

二叉树的递归实现:以先序遍历为例说明,后两种相同。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> path;
    void preorder(TreeNode* root) {
        if (root == 0)
            return;
        path.push_back(root->val);
        preorder(root->left);
        preorder(root->right);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        preorder(root);
        return path;
    }
};

成员变量path是private或public都可以,中序和后序遍历只是把位置换一下就可以了。

二叉树遍历非递归实现

二叉树先序遍历非递归实现

思路:
先序遍历,用辅助栈,因为是按出栈顺序依次访问二叉树的结点,要求先访问左子树再访问右子树,栈是先进后出,所以入栈是先右子树入栈,再左子树入栈,保证出栈时左子树先被访问到。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> path;
        if (root == 0)
            return path;
        stack<TreeNode *> stk;
        stk.push(root);
        while (!stk.empty()) {
            TreeNode *temp = stk.top();
            path.push_back(temp->val);
            stk.pop();
            if (temp->right)
                stk.push(temp->right);
            if (temp->left)
                stk.push(temp->left);
        }
        return path;
    }
};

二叉树中序遍历非递归实现

思路:
《严书》有讲解过中序遍历的两种非递归实现。中序遍历,先遍历左子树再遍历右子树,左子树遍历到极左,从根结点开始,只要左子树非空,一直将左子树入栈,直到左子树是空,处栈空结点,遍历当前层的根结点,开始遍历右子树。《严书》P130写的很清晰,遍历右子树时不再需要保存当前层的根指针,可直接修改栈顶记录中的指针即可。
解法1:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> path;
        if (root == 0)
            return path;
        stack<TreeNode *> stk;
        stk.push(root);
        while (!stk.empty()) {
            while (stk.top())
                stk.push(stk.top()->left);
            stk.pop();
            if (!stk.empty()) {
                TreeNode *temp = stk.top();
                stk.pop();
                path.push_back(temp->val);
                stk.push(temp->right);
            }
        }
        return path;
    }
};

解法2思路:
类似于解法1思路,但变成了一个while循环,此方法更好。移动指针p,只要p非空,将p的左子树入栈,当p是空时,即到了极左结点,中序遍历,访问当前层的根结点,p指向当前根结点的右子树,开始访问右子树。另外的判断是栈是否为空,如果栈空了,说明遍历结束。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> path;
        if (root == 0)
            return path;
        stack<TreeNode *> stk;
        TreeNode *p;
        p = root;
        /* 有可能p为空,但栈非空,仍有结点未遍历 */
        while (p || !stk.empty()) {
            if (p) {
                stk.push(p);
                p = p->left;
            } else {
                p = stk.top();
                stk.pop();
                path.push_back(p->val);
                p = p->right;
            }
        }
        return path;
    }
};

二叉树后序遍历非递归实现

后序遍历参考:http://www.cnblogs.com/rain-lei/p/3705680.html
思路1:
对于节点p可以分情况讨论
1. p如果是叶子节点,直接输出
2. p如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈
3. p如果有孩子,而且孩子都已经访问过,则访问p节点

如何来表示出p的孩是否都已经访问过了呢?
最暴力的方法就是对每个节点的状态进行保存,这么做显然是可以的,但是空间复杂度太大了。
我们可以保存最后一个访问的节点last,如果满足 (p->right==NULL && last ==p->left) || last=p->right,那么显然p的孩子都访问过了,接下来可以访问p。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> path;
        if (root == 0)
            return path;
        stack<TreeNode *> stk;
        TreeNode *last, *p;
        last = root;
        stk.push(root);
        while (!stk.empty()) {
            p = stk.top();
            if ((p->left == 0 && p->right == 0) || (p->right == 0 && last == p->left) || (last == p->right)) {
                path.push_back(p->val);
                last = p;
                stk.pop();
            } else {
                if (p->right)
                    stk.push(p->right);
                if (p->left)
                    stk.push(p->left);
            }
        }
        return path;
    }
};

思路2:
其实我们希望栈中保存的从顶部依次是root->left, root->right, root,当符合上面提到的条件时,就进行出栈操作。有一种巧妙的方法可以做到,先上代码。

vector<int> postOrder(TreeNode *root)
{
    vector<int> res;
    if(root == NULL) return res;

    TreeNode *p = root;
    stack<TreeNode *> sta;
    sta.push(p);
    sta.push(p);
    while(!sta.empty())
    {
        p = sta.top(); sta.pop();
        if(!sta.empty() && p==sta.top())
        {
            if(p->right) sta.push(p->right), sta.push(p->right);
            if(p->left) sta.push(p->left), sta.push(p->left);
        }
        else
            res.push_back(p->val);
    }

    return res;
}

对于每个节点,都压入两遍,在循环体中,每次弹出一个节点赋给p,如果p仍然等于栈的头结点,说明p的孩子们还没有被操作过,应该把它的孩子们加入栈中,否则,访问p。也就是说,第一次弹出,将p的孩子压入栈中,第二次弹出,访问p。
太困了,先回去睡觉了,任务完成75%。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
To convert the given array to a complete BST, we need to perform the following steps: 1. Sort the array in ascending order 2. Construct a complete binary tree using the sorted array 3. Perform inorder traversal of the binary tree and store the elements in the original array in the same order as the traversal Here's the implementation of the to_bst(lst) function in Python: ```python def to_bst(lst): # Sort the input list lst.sort() # Construct a complete binary tree using the sorted list n = len(lst) if n == 0: return lst root = lst[n // 2] left_subtree = to_bst(lst[:n // 2]) right_subtree = to_bst(lst[n // 2 + 1:]) binary_tree = [root] + left_subtree + right_subtree # Perform inorder traversal of the binary tree and store the elements in the original array inorder_traversal(binary_tree, lst, 0) return lst def inorder_traversal(binary_tree, lst, i): # Perform inorder traversal of the binary tree and store the elements in the original array n = len(binary_tree) if i >= n: return inorder_traversal(binary_tree, lst, 2 * i + 1) lst[i] = binary_tree[i] inorder_traversal(binary_tree, lst, 2 * i + 2) ``` The to_bst(lst) function takes in the input list and returns the same list after converting it to a complete BST. The function first sorts the input list in ascending order. It then constructs a complete binary tree using the sorted list by recursively dividing the list into two halves and setting the middle element as the root of the binary tree. Finally, the function performs an inorder traversal of the binary tree and stores the elements in the original list in the same order as the traversal.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值