面试题25二叉树中和为某一值的路径

https://blog.csdn.net/u010425776/article/details/50903195

 

 

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

 

 

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

 

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

 
  1. /**

  2. * 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。

  3. * PS:从根结点开始,一直到叶子结点形式一条路径。

  4. * @author 大闲人柴毛毛

  5. * @date 2016年3月15日

  6. */

  7. public class PrintBinaryPath {

  8. /**

  9. * 分析:要找出路径之和为指定整数的路径,就需要遍历二叉树的所有路径。

  10. * 此外,由于路径是指根结点到叶子结点的线段,因此我们想到采用深度优先的方式遍历二叉树。

  11. * 深度优先算法又分为:先序遍历、中序遍历、后序遍历,其中先序遍历符合我们的要求。

  12. */

  13.  
  14. /**

  15. * 首先需要创建一个栈,用来保存当前路径的结点。

  16. * 采用先序遍历算法遍历结点时,先将途中经过的结点均存入栈中,然后判断当前结点是否为叶子结点,若不是叶子结点的话,则递归遍历该结点的左孩子和右孩子;

  17. * 若是叶子结点的话,计算下当前栈中所有结点之和是否为指定的整数,若是的话打印栈中所有元素。

  18. * 然后这个函数在返回之前,将当前叶子结点从栈中删除。

  19. */

  20.  
  21. /**

  22. * 打印二叉树中路径之和为n的路径

  23. * @param root 二叉树

  24. * @param n 路径之和

  25. * @return 返回函数能否正确执行

  26. */

  27. public static boolean printBinaryPath(BinaryTreeNode<Integer> root,int n){

  28. //树为空

  29. if(root==null){

  30. System.out.println("树为空!");

  31. return false;

  32. }

  33.  
  34. //n小于0

  35. if(n<=0){

  36. System.out.println("n小于等于0!");

  37. return false;

  38. }

  39.  
  40. //创建栈

  41. Stack<Integer> stack = new Stack<Integer>();

  42. //开始递归查找路径

  43. printBinaryPath(root,n,stack);

  44.  
  45. return true;

  46. }

  47.  
  48.  
  49.  
  50. /**

  51. * 递归寻找路径之和为n的路径

  52. * @param root 二叉树根结点

  53. * @param n 指定整数

  54. * @param stack 用于保存当前路径的栈

  55. */

  56. private static void printBinaryPath(BinaryTreeNode<Integer> root, int n, Stack<Integer> stack) {

  57. //若当前根结点为叶子结点

  58. if(root.left==null && root.right==null){

  59. //将叶子结点入栈

  60. stack.add(root.data);

  61.  
  62. //计算当前路径之和

  63. int sum = 0;

  64. Iterator<Integer> it = stack.iterator();

  65. while(it.hasNext())

  66. sum += it.next();

  67.  
  68. //若当前路径之和==n,则打印这条路径

  69. if(sum==n){

  70. Iterator<Integer> it2 = stack.iterator();

  71. while(it2.hasNext())

  72. System.out.print(it2.next()+",");

  73. System.out.println("\n-------------------");

  74. }

  75.  
  76. //将当前叶子结点出栈

  77. stack.pop();

  78.  
  79. //返回上层结点

  80. return;

  81. }

  82.  
  83. //若当前结点为非叶子结点

  84. else{

  85. //将根结点入栈

  86. stack.add(root.data);

  87.  
  88. //若左孩子存在,递归左孩子

  89. if(root.left!=null)

  90. printBinaryPath(root.left,n,stack);

  91.  
  92. //若右孩子存在,递归右孩子

  93. if(root.right!=null)

  94. printBinaryPath(root.right,n,stack);

  95.  
  96. //将当前叶子结点出栈

  97. stack.pop();

  98.  
  99. //返回上层结点

  100. return;

  101. }

  102. }

  103.  
  104.  
  105.  
  106. /**

  107. * 测试

  108. */

  109. public static void main(String[] args){

  110. //构建二叉树

  111. BinaryTreeNode<Integer> node1 = new BinaryTreeNode<Integer>();

  112. BinaryTreeNode<Integer> node2 = new BinaryTreeNode<Integer>();

  113. BinaryTreeNode<Integer> node3 = new BinaryTreeNode<Integer>();

  114. BinaryTreeNode<Integer> node4 = new BinaryTreeNode<Integer>();

  115. BinaryTreeNode<Integer> node5 = new BinaryTreeNode<Integer>();

  116.  
  117. node1.data = 10;

  118. node2.data = 5;

  119. node3.data = 12;

  120. node4.data = 4;

  121. node5.data = 7;

  122.  
  123. node1.left = node2;

  124. node1.right = node3;

  125.  
  126. node2.left = node4;

  127. node2.right = node5;

  128.  
  129. printBinaryPath(node1,19);

  130. }

  131. }

  132.  
  133.  
  134.  
  135.  
  136. /**

  137. * 二叉树的结点

  138. */

  139. class BinaryTreeNode<T>{

  140. T data;//结点的数据域

  141. BinaryTreeNode<T> left;//左子树

  142. BinaryTreeNode<T> right;//右子树

  143. }

  144.  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值