剑指offer代码解析——面试题25二叉树中和为某一值的路径

题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。PS:从根结点开始,一直到叶子结点形式一条路径。

分析:要找出路径之和为指定整数的路径,就需要遍历二叉树的所有路径。此外,由于路径是指根结点到叶子结点的线段,因此我们想到采用深度优先的方式遍历二叉树。深度优先算法又分为:先序遍历、中序遍历、后序遍历,其中先序遍历符合我们的要求。

首先需要创建一个栈,用来保存当前路径的结点。采用先序遍历算法遍历结点时,先将途中经过的结点均存入栈中,然后判断当前结点是否为叶子结点,若不是叶子结点的话,则递归遍历该结点的左孩子和右孩子;若是叶子结点的话,计算下当前栈中所有结点之和是否为指定的整数,若是的话打印栈中所有元素。然后这个函数在返回之前,将当前叶子结点从栈中删除。代码如下:

/**
 * 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
 * PS:从根结点开始,一直到叶子结点形式一条路径。
 * @author 大闲人柴毛毛
 * @date 2016年3月15日
 */
public class PrintBinaryPath {
	/**
	 * 分析:要找出路径之和为指定整数的路径,就需要遍历二叉树的所有路径。
	 * 此外,由于路径是指根结点到叶子结点的线段,因此我们想到采用深度优先的方式遍历二叉树。
	 * 深度优先算法又分为:先序遍历、中序遍历、后序遍历,其中先序遍历符合我们的要求。
	 */
	
	/**
	 * 首先需要创建一个栈,用来保存当前路径的结点。
	 * 采用先序遍历算法遍历结点时,先将途中经过的结点均存入栈中,然后判断当前结点是否为叶子结点,若不是叶子结点的话,则递归遍历该结点的左孩子和右孩子;
	 * 若是叶子结点的话,计算下当前栈中所有结点之和是否为指定的整数,若是的话打印栈中所有元素。
	 * 然后这个函数在返回之前,将当前叶子结点从栈中删除。
	 */
	
	/**
	 * 打印二叉树中路径之和为n的路径
	 * @param root 二叉树
	 * @param n 路径之和
	 * @return 返回函数能否正确执行
	 */
	public static boolean printBinaryPath(BinaryTreeNode<Integer> root,int n){
		//树为空
		if(root==null){
			System.out.println("树为空!");
			return false;
		}
		
		//n小于0
		if(n<=0){
			System.out.println("n小于等于0!");
			return false;
		}
		
		//创建栈
		Stack<Integer> stack = new Stack<Integer>();
		//开始递归查找路径
		printBinaryPath(root,n,stack);
		
		return true;
	}

	
	
	/**
	 * 递归寻找路径之和为n的路径
	 * @param root 二叉树根结点
	 * @param n 指定整数
	 * @param stack 用于保存当前路径的栈
	 */
	private static void printBinaryPath(BinaryTreeNode<Integer> root, int n, Stack<Integer> stack) {
		//若当前根结点为叶子结点
		if(root.left==null && root.right==null){
			//将叶子结点入栈
			stack.add(root.data);
			
			//计算当前路径之和
			int sum = 0;
			Iterator<Integer> it = stack.iterator();
			while(it.hasNext())
				sum += it.next();
			
			//若当前路径之和==n,则打印这条路径
			if(sum==n){
				Iterator<Integer> it2 = stack.iterator();
				while(it2.hasNext())
					System.out.print(it2.next()+",");
				System.out.println("\n-------------------");
			}
			
			//将当前叶子结点出栈
			stack.pop();
			
			//返回上层结点
			return;
		}
		
		//若当前结点为非叶子结点
		else{
			//将根结点入栈
			stack.add(root.data);
			
			//若左孩子存在,递归左孩子
			if(root.left!=null)
				printBinaryPath(root.left,n,stack);
			
			//若右孩子存在,递归右孩子
			if(root.right!=null)
				printBinaryPath(root.right,n,stack);
			
			//将当前叶子结点出栈
			stack.pop();
			
			//返回上层结点
			return;
		}
	}
	
	
	
	/**
	 * 测试
	 */
	public static void main(String[] args){
		//构建二叉树
		BinaryTreeNode<Integer> node1 = new BinaryTreeNode<Integer>();
		BinaryTreeNode<Integer> node2 = new BinaryTreeNode<Integer>();
		BinaryTreeNode<Integer> node3 = new BinaryTreeNode<Integer>();
		BinaryTreeNode<Integer> node4 = new BinaryTreeNode<Integer>();
		BinaryTreeNode<Integer> node5 = new BinaryTreeNode<Integer>();
		
		node1.data = 10;
		node2.data = 5;
		node3.data = 12;
		node4.data = 4;
		node5.data = 7;
		
		node1.left = node2;
		node1.right = node3;

		node2.left = node4;
		node2.right = node5;
		
		printBinaryPath(node1,19);
	}
}




/**
 * 二叉树的结点
 */
class BinaryTreeNode<T>{
	T data;//结点的数据域
	BinaryTreeNode<T> left;//左子树
	BinaryTreeNode<T> right;//右子树
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

bash shell 中如何区别$和${}和$和

$()和${}的用法: 在 bash shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换用(command substitution)的。而...

33716
来自专栏mathor

LeetCode160.相交链表

 两种做法,第一种,创建一个HashSet,先把A链表的所有节点保存到Set中,然后遍历B链表,将B链表的所有节点保存进去,保存时进行判断,如果Set中已经...

723
来自专栏算法channel

Leetcode|二叉树非递归版后序遍历

二叉树的非递归版后序遍历,首先定义TreeNode如下: """ TreeNode class """ class TreeNode(object): ...

3134
来自专栏武培轩的专栏

剑指Offer-二叉搜索树与双向链表

题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 思路 思路一: 由于要求链表是有序...

2553
来自专栏Bingo的深度学习杂货店

Q110 Balanced Binary Tree

Given a binary tree, determine if it is height-balanced. For this problem, a hei...

2675
来自专栏赵俊的Java专栏

两个链表的交叉

1393
来自专栏肖洒的博客

数据结构笔记(二)

栈是限定仅在表尾进行插入和删除操作的线性表。 队列是只允许在一段进行插入操作、而在另一端进行删除操作的线性表。

693
来自专栏Jack-Cui

234. Palindrome Linked List(Linked List-Easy)

Given a singly linked list, determine if it is a palindrome. Follow up: Could yo...

18510
来自专栏尾尾部落

[剑指offer] 整数中1出现的次数(从1到n整数中1出现的次数)

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次...

422
来自专栏尾尾部落

[剑指offer] 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

491

扫描关注云+社区