横向打印二叉树

    第四届蓝桥杯决赛 java高职高专组 第四题

 横向打印二叉树

    二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。

    当遇到空子树时,则把该节点放入那个位置。 

    比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如图1所示。 

    本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。 

    输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
    输入数据中没有重复的数字。 

    输出该排序二叉树的横向表示。 对应上例中的数据,应输出:

   |-12
10-|
   |-8-|
       |   |-7
       |-5-|
           |-4


    为了便于评卷程序比对空格的数目,请把空格用句点代替:
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4

例如:
用户输入:
10 5 20
则程序输出:
...|-20
10-|
...|-5

再例如:
用户输入:
5 10 20 8 4 7
则程序输出:
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4


资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 1000ms

import java.util.Scanner;


public class 横向打印二叉树 {
	/**
	 * 节点
	 */
	static class Node{
		//值
		int data;
		Node left;
		Node right;
		//输出的值
		String s;
		public Node(int e){
			this.data=e;
		}
	}
	
	public static void main(String[] args) {
		//int[] n = { 34, 31, 36, 47, 23, 35, 41, 14, 12, 15, 7, 10, 8, 5, 12, 7, 3, 6 };
		int[] n=getInput();
		Node root=new Node(n[0]);
		root.s=root.data+"-|";
		
		for(int i=1;i<n.length;i++){
			Node node=new Node(n[i]);
			if(node.data>root.data){
				addRight(node, root,0);
			}else{
				addLeft(node,root,0);
			}
		}
		
		print(root);
	}
	/**
	 * 接收输入
	 * @return
	 */
	public static int[] getInput(){
		Scanner scan=new Scanner(System.in);
		String s=scan.nextLine();
		String[] ss=s.split(" ");
		int[] nn=new int[ss.length];
		for(int i=0;i<ss.length;i++){
			nn[i]=Integer.parseInt(ss[i]);
		}
		return nn;
	}
	/**
	 * 打印
	 * @param node 根节点
	 */
	public static void print(Node node){
		//始终先打印右节点,然后打印本身,最后打印左节点
		if(node.right!=null){
			print(node.right);
		}
		//如果没有子节点,就不打印后面的"-|“
		if(node.left==null&&node.right==null){
			System.out.println(node.s.substring(0, node.s.length()-2));
		}else{
			System.out.println(node.s);
		}
		if(node.left!=null){
			print(node.left);
		}
	}
	/**
	 * 添加右节点
	 * @param node 子节点
	 * @param root 父节点
	 * @param flag 括号层数(0 只有一层括号,1 有多层括号)
	 */
	public static void addRight(Node node,Node root,int flag){
		if(root.right==null){
			node.s=root.s.replaceAll("[0-9]|-", ".").substring(0, root.s.length()-1);
			if(flag==0){
				int index=node.s.lastIndexOf("|");
				if(index!=-1){
					node.s=node.s.substring(0,index)+"."+node.s.substring(index+1);
				}
			}
			node.s+="|-"+node.data+"-|";
			
			root.right=node;
		}else if(node.data>root.right.data){
			addRight(node, root.right,0);
		}else{
			addLeft(node,root.right,1);
		}
	}
	/**
	 * 添加左节点
	 * @param node 子节点
	 * @param root 父节点
	 * @param flag 括号层数(0 只有一层括号,1 有多层括号)
	 */
	public static void addLeft(Node node,Node root,int flag){
		if(root.left==null){
			node.s=root.s.replaceAll("[0-9]|-", ".").substring(0, root.s.length()-1);
			if(flag==0){
				int index=node.s.lastIndexOf("|");
				if(index!=-1){
					node.s=node.s.substring(0,index)+"."+node.s.substring(index+1);
				}
			}
			node.s+="|-"+node.data+"-|";
			root.left=node;
		}else if(node.data>root.left.data){
			addRight(node, root.left,1);
		}else{
			addLeft(node,root.left,0);
		}
	}
}


### 蓝桥杯比赛中的二叉树横向打印解决方案 #### 方法概述 在蓝桥杯比赛中,涉及到二叉树的题目通常会考察选手对数据结构的理解以及算法设计能力。对于二叉树横向打印问题,可以通过广度优先遍历(BFS, Breadth-First Search)来解决[^1]。这种方法利用队列的数据结构逐层访问二叉树的节点。 #### 广度优先搜索实现 以下是基于队列的广度优先搜索实现方式: ```python from collections import deque class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def levelOrder(root: TreeNode): result = [] if not root: return result queue = deque([root]) while queue: current_level_size = len(queue) current_level_nodes = [] for _ in range(current_level_size): node = queue.popleft() current_level_nodes.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(current_level_nodes) return result ``` 上述代码定义了一个 `TreeNode` 类表示二叉树的节点,并通过函数 `levelOrder` 来完成层次遍历并返回每一层的结果列表[^2]。 #### 动态规划与递归的关系 虽然动态规划和递归并不是直接应用于二叉树横向打印的方法,但在某些情况下,可以结合这两种技术优化复杂度较高的问题。例如,在编码实现动态规划时,可以选择自顶向下的记忆化搜索或者自底向上的递推方法[^3]。然而,这些方法并不适用于本题的核心逻辑——即如何按层输出二叉树的内容。 #### 排序二叉树的应用背景 值得注意的是,二叉树本身也可以作为一种排序工具。当构建一棵排序二叉树时,每次插入新节点都会依据其值大小决定放置于左子树还是右子树中[^4]。尽管此特性不直接影响横向打印的过程,但它有助于理解二叉树的整体性质及其应用范围。 #### 总结 综上所述,针对蓝桥杯比赛中可能遇到的二叉树横向打印问题,推荐采用广度优先搜索策略配合队列操作进行求解。该方法能够有效保证按照从上到下、从左至右顺序依次展示各层节点值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值