从左往右 从上往下 按层遍历 输出 树 二叉树

需求

将二叉树的 各节点输出, 按照层级输出


     4
   /   \
  2     7
 / \   / \
1   3 6   9

方法1

public static void outputTree(TreeNode root) {
    if (root == null) {
        return;
    }
    System.out.println(root);
    List<TreeNode> former = new ArrayList<TreeNode>();
    former.add(root);
    while (former.size() != 0) {

        List<TreeNode> current = new ArrayList<TreeNode>();

        for (TreeNode node : former) {
            System.out.print(node.left + ", ");
            System.out.print(node.right + ", ");
            if (node.left != null) {
                current.add(node.left);
            }
            if (node.right != null) {
                current.add(node.right);
            }
        }
        System.out.println();
        former.clear();
        former.addAll(current);
    }
}

思路

因为按照层输出, 所有用两个 list 变量. 一个保存 这层的 节点, 一个保存所有这层节点的子节点

缺陷

对于某些子节点为空的节点支持得不是很好

为空的节点在中间时, 输出也会有些偏差


方法1 输出

8
4, 10, 
2, null, 9, 12, 
1, null, null, null, null, null, 
null, null, 
### 回答1: 这道题目需要我们根据二叉树的先序和中序遍历结果来构建二叉树,然后再按照层次遍历的方式输出二叉树的节点值。 具体的做法是,首先根据先序和中序遍历结果构建二叉树。先序遍历结果中的第一个节点是根节点,我们可以在中序遍历结果中找到根节点的位置,然后将中序遍历结果分成左子和右子两部分。接下来,我们可以递归地构建左子和右子。 构建好二叉树之后,我们可以按照层次遍历的方式输出节点值。具体的做法是,使用一个队列来存储待输出的节点。首先将根节点入队,然后每次从队列中取出一个节点,输出它的值,并将它的左右子节点入队。重复这个过程,直到队列为空。 代码实现比较复杂,需要考虑很多细节,这里就不给出具体的代码了。 ### 回答2: 首先,我们需要了解二叉树按层遍历的方法。按层遍历是一种广度优先遍历,可以使用队列来实现。首先,将根节点入队,然后进入循环,每次从队列中取出一个节点,打印该节点的值,并将该节点的左右子节点(如果存在)入队。重复此过程,直到队列为空。 根据先序和中序遍历的结果,我们可以找到根节点,以及左右子在中序遍历结果中的位置。我们可以递归重建二叉树,并按照上述方法按层遍历。 具体过程如下: 1. 在先序遍历结果中找到第一个节点,即为根节点。 2. 在中序遍历结果中找到根节点,左侧为左子,右侧为右子。 3. 递归重建左子和右子。 4. 按照上述方法按层遍历二叉树。 具体实现过程可以参考如下Python代码: ``` class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right # 构造二叉树 def build_tree(preorder, inorder): if not preorder: return None # 找到根节点 root = TreeNode(preorder[0]) # 找到根节点在中序遍历结果中的位置 idx = inorder.index(preorder[0]) # 递归构造左子和右子 root.left = build_tree(preorder[1:idx+1], inorder[:idx]) root.right = build_tree(preorder[idx+1:], inorder[idx+1:]) return root # 按层遍历二叉树 def level_order(root): if not root: return [] queue = [root] res = [] while queue: size = len(queue) level = [] for i in range(size): node = queue.pop(0) level.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) res.append(level) return res # 测试样例 preorder = [1, 2, 4, 5, 3, 6, 7] inorder = [4, 2, 5, 1, 6, 3, 7] root = build_tree(preorder, inorder) print(level_order(root)) # [[1], [2, 3], [4, 5, 6, 7]] ``` 上述代码中,`build_tree`函数用于递归重建二叉树,`level_order`函数用于按层遍历二叉树。测试样例的先序遍历结果为`[1, 2, 4, 5, 3, 6, 7]`,中序遍历结果为`[4, 2, 5, 1, 6, 3, 7]`,输出结果为`[[1], [2, 3], [4, 5, 6, 7]]`,即表示按层遍历后的结果。 ### 回答3: 题目描述: 给定一棵二叉树的先序(根、左、右)和中序(左、根、右)的打印结果,输出二叉树按层从左往右)打印结果。 解题思路: 根据先序遍历的顺序,我们可以得到二叉树的根节点,然后根据中序遍历的结果,我们可以将二叉树分成左子和右子。那么左子的先序遍历和中序遍历序列就分别是原先序遍历和原中序遍历序列中除去根节点及其右子的部分,右子的先序遍历和中序遍历序列就分别是原先序遍历和原中序遍历序列中除去根节点及其左子的部分。 那么我们可以递归的去构建左子和右子,直到遇到空节点为止。 最后按照层序遍历的顺序,将每层节点依次保存到一个二维数组中,并输出即可。 具体步骤: 1.根据先序遍历的结果,获取二叉树根节点 root; 2.根据中序遍历的结果,将分为左右子; 3.递归构建左子和右子; 4.按照层序遍历的顺序将每层节点保存到一个二维数组中; 5.输出二维数组即为答案。 代码实现: ``` #include<iostream> #include<vector> #include<queue> #include<unordered_map> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; unordered_map<int, int> index; //用于存放中序遍历中每个节点的索引位置 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, int pre_left, int pre_right, int in_left, int in_right) { if (pre_left > pre_right) return nullptr; //子为空 int pre_root = pre_left; //根节点为子的最左边 int in_root = index[preorder[pre_root]]; //获取根节点在中序遍历中的索引位置 TreeNode* root = new TreeNode(preorder[pre_root]); //构建根节点 int left_len = in_root - in_left; //获取左子的长度 //递归构建左右子 root->left = buildTree(preorder, inorder, pre_left + 1, pre_left + left_len, in_left, in_root - 1); root->right = buildTree(preorder, inorder, pre_left + left_len + 1, pre_right, in_root + 1, in_right); return root; } vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> res; if (!root) return res; //节点为空,返回空 queue<TreeNode*> q; q.push(root); while (!q.empty()) { int n = q.size(); vector<int> level; for (int i = 0; i < n; i++) { TreeNode* node = q.front(); q.pop(); level.push_back(node->val); if (node->left) q.push(node->left); if (node->right) q.push(node->right); } res.push_back(level); } return res; } int main() { vector<int> preorder = { 1,2,4,5,3,6,7 }; vector<int> inorder = { 4,2,5,1,6,3,7 }; int size = inorder.size(); for (int i = 0; i < size; i++) { index[inorder[i]] = i; } TreeNode* root = buildTree(preorder, inorder, 0, size - 1, 0, size - 1); vector<vector<int>> res = levelOrder(root); for (auto level : res) { for (auto node : level) { cout << node << " "; } cout << endl; } return 0; } ``` 时间复杂度:O(n) 空间复杂度:O(n) 其中n为二叉树的节点数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值