从上往下打印二叉树,判断该数组是不是某二叉搜索树的后序,前序,或者是中序遍历的结果,二叉树中和为某一值的路径

题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

解题思路
就是二叉树的层序遍历。借助一个队列就可以实现。
使用两个队列一个存放节点,一个存放值。先将根节点加入到队列中,然后遍历队列中的元素,遍历过程中,访问该元素的左右节点,再将左右子节点加入到队列中来。

	public void print(TreeNode node) {
		LinkedList<TreeNode> list = new LinkedList<TreeNode>();
		// 首先将整个二叉树的根节点入队列
		list.offer(node);
		int next=0;//下一层的节点数
		int tobeprint=1;//表示当前层没有打印的节点数
		while (!list.isEmpty()) {// 如果队列中不再具有节点,说明整个二叉树遍历完成
			// 首先将队列头节点出队列
			TreeNode node1 = list.pop();
			if (node1 != null) {
				System.out.print(node1.data);
				// 如果队列头结点左孩子不是空,则将左孩子入队列
				if (node1.left != null) {
					list.offer(node1.left);
					++next;
				}
				// 如果队列头节点右孩子不是空,则将右孩子入队列
				if (node.right != null) {
					list.offer(node1.right);
					++next;
				}
				--tobeprint;
				if(tobeprint==0) {
					System.out.println();
					tobeprint=next;
					next=0;
				}
				
			}

		}
	}

运行结果(按层打印的结果)
在这里插入图片描述
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

解题思路

二叉搜索树: 左子树<根<=右子树

对于后序遍历来说,序列数组的最后一个元素一定是根节点, 根据这个元素,将前面的数组分为左、右两个部分,左侧部分都比该元素小,右侧部分都比该元素大,如果右侧部分有比该根节点小的元素,那么就不是后序遍历,如此递归进行。

/**
 * 二叉搜索树的后序遍历序列
 * @author xhh
 *
 */
public class ThrityThree {
	public boolean verifySquenceOfBST(int[] squence,int start,int length) {
		if(squence.length==0) {
			return false;
		}
		if(squence.length==1) {
			return true;
		}
		return judge(squence,0,squence.length-1);
	}
	public boolean judge(int[] squence,int start,int end) {
		if(start>=end) {
			return true;
		}
		int i=start;
		while(i<end && squence[i]<squence[end]) {
			i++;
		}
		for(int j=i;j<end;j++) {
			if(squence[j]<squence[end]) {
				return false;
			}
		}
		return (judge(squence, start, i-1))&&(judge(squence,i, end-1));
	}
	public static void main(String[] args) {
		int[] a=new int[] {5,7,6,9,11,10,8};
		ThrityThree thrityThree = new ThrityThree();
		System.out.println(thrityThree.verifySquenceOfBST(a, 0, a.length));
		
	}
}

所以同样的原理,我们可以判读搜索树是不是前序

二叉搜索树: 左子树<根<=右子树

	/**
	 * 先序
	 * 
	 * @param xhh
	 */
	public boolean verifySquenceOfPre(int[] squence) {
		if (squence.length == 0) {
			return false;
		}
		if (squence.length == 1) {
			return true;
		}
		return judgePre(squence, 0, squence.length - 1);
	}

	private boolean judgePre(int[] squence, int start, int end) {
		if (start >= end) {
			return true;
		}
		int i = start + 1;
		while (i < end && squence[start] > squence[i]) {
			i++;
		}
		int j = i;
		for (; j < end; j++) {
			if (squence[j] < squence[start]) {
				return false;
			}
		}
		return (judgePre(squence, start + 1, i - 1)) && (judgePre(squence, i, end));
	}

最简单的就是中序,只要数组是有序的,那么就是二叉搜索树的中序遍历结果

题目描述
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

解题思路
用前序遍历的方式访问到某一结点时,把该结点添加到路径上,并用目标值减去该节点的值。如果该结点为叶结点并且目标值减去该节点的值刚好为0,则当前的路径符合要求,我们把加入res数组中。如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到它的父结点。因此我们在函数退出之前要在路径上删除当前结点,以确保返回父结点时路径刚好是从根结点到父结点的路径。

/**
 * 二叉树中和为某一值的路径
 * @author xhh
 *
 */

import java.util.ArrayList;

public class ThrityFour {
	public ArrayList<ArrayList<Integer>> result = new ArrayList<>();
	ArrayList<Integer> tmp = new ArrayList<>();

	public ArrayList<ArrayList<Integer>> findPath(TreeNode node, int exceptSum) {
		if (node == null) {
			return result;
		}
		exceptSum = exceptSum - node.data;
		tmp.add(node.data);
		if (exceptSum == 0 && node.left == null && node.right == null) {
			result.add(new ArrayList<Integer>(tmp));
		}
		else {
			findPath(node.left, exceptSum);
			findPath(node.right, exceptSum);
		}
		tmp.remove(tmp.size()-1);
		return result;
	}
	public static void main(String[] args) {
		ThrityFour thrityFour = new ThrityFour();
		TreeNode node1=new TreeNode(10);
		TreeNode node2=new TreeNode(5);
		TreeNode node3=new TreeNode(12);
		TreeNode node4=new TreeNode(4);
		TreeNode node5=new TreeNode(7);
		node1.left=node2;
		node1.right=node3;
		node2.left=node4;
		node2.right=node5;
		ArrayList<ArrayList<Integer>> findPath = thrityFour.findPath(node1, 22);
		System.out.println(findPath.toString());
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值