4在二元树中找出和为某一值的所有路径

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4249910.html

声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,故原出处已不好查到,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。 

题目:输入一个整数和一棵二叉树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

  例如 输入整数22和如下二叉树
   10 
   /   
   5 12  
   /     
  4     7
  则打印出两条路径:10, 12和10, 5, 7。
  
设计思路:
  1. 输入一个整形数组和一个整数,根据数组创建二叉树
  2.用一个将当前路径的节点列表path 和总路径列表pathlist分别保存到LinkedList里,用一个变量(currentSum)保存当前节点值之和
    a).若树为空,则结束查找。
    b).将当前节点的值累加到currentSum,将当前节点累加到path。
    c).若当前节点已经是叶子节点并且currentSum等于你的期望值,则将path累加到pathlist。
    d).如果当前节点不为叶子结点,则递归查找它的左右孩子结点。
    e).将当前结点从当前路径里删除,currentSum返回累加之前的值  ,及恢复到当前节点的父节点状态。
 
注:我创建的是一颗二叉排序树,若想创建其他类型的树则可将创建树的过程稍作修改。
java 实现代码如下:
 
  1 package com.interview;
  2 
  3 import java.util.LinkedList;
  4 
  5 /**
  6  * 在二元树中找出和为某一值的所有路径
  7  * 注:此处建立的是一颗排序二叉树
  8  * @author wjh
  9  *
 10  */
 11 
 12 public class _4SearchPath {
 13 
 14     /**
 15      * @param args
 16      */
 17     public _4SearchPath() {
 18         super();
 19         // TODO Auto-generated constructor stub
 20     }
 21 
 22     public static void main(String[] args) {
 23         int[] first = {10,5,12,4,7};
 24         LinkedList<Node> path = new LinkedList<Node>(); //保存路径
 25         LinkedList<LinkedList<Node>> pathlist = new LinkedList<LinkedList<Node>>();  //保存路径列表
 26         Node root = null;
 27         root = createTree( root, first);   //1)建树
 28         searchPath(root, 22, 0,  path,pathlist);//2)查找路径
 29         System.out.println("这是所有的路径:");
 30         printPath(pathlist);    //3)打印路径
 31     }
 32     
 33     //在二元树中找出和为某一值的所有路径
 34     private static void searchPath(Node root, int yourSum, int  currentSum, LinkedList<Node> path, 
 35             LinkedList<LinkedList<Node>> pathlist){
 36         if( root==null )
 37              return;
 38         currentSum += root.data;  //将当前结点值累加至当前和变量中
 39         path.add(root);      //结点加入到路径里
 40         /**
 41          * 如果当前的结点为叶子结点,且和为你输入的值,则将路径 加入到李静列表里
 42          * 若无需保存路径列表,在在此直接打印path,不用添加到pathlist里
 43          */
 44         if(root.left==null && root.right==null && currentSum == yourSum){
 45             LinkedList<Node> temppath = new LinkedList<Node>();  
 46             for(Node node: path){
 47                 temppath.add(node);
 48             }
 49             pathlist.add(temppath);  //没有直接add(path) 是因为path在之后的过程中会被改变
 50         }
 51         /**如果当前节点不为叶子结点,则递归查找它的左右孩子结点*/
 52         if(root.left!=null)
 53             searchPath(root.left, yourSum, currentSum, path, pathlist);
 54         if(root.right!=null)
 55             searchPath(root.right, yourSum, currentSum, path, pathlist);
 56         /**当前结点从当前路径里删除,currentSum返回累加之前的值  ,及恢复到当前节点的父节点状态*/
 57         currentSum -= root.data;
 58         path.removeLast();
 59     }
 60     
 61     //打印所有路径
 62     private static void printPath(LinkedList<LinkedList<Node>> pathlist){
 63         for(LinkedList<Node> path: pathlist){
 64             int n = path.size();
 65             for(int i=0;i<n;i++){
 66                 if(i<n-1)
 67                     System.out.print(path.get(i).data+"-->");
 68                 else 
 69                     System.out.print(path.get(i).data);
 70             }
 71             System.out.println();
 72         }
 73     }
 74         
 75     //创建二叉排序树
 76     public static Node  createTree(Node root, int[] r){
 77         int n = r.length;
 78         System.out.println("建树过程(a<--b表示在a左边插入b;a-->b表示在a右边插入b):");
 79         for(int i=0;i<n;i++){
 80             Node child = new Node(r[i],null,null);
 81             root = insert(root, child);
 82         }
 83         return root;
 84     }
 85         
 86     //二叉排序树的插入算法
 87     public static Node insert(Node root, Node child){
 88         //寻找插入位置
 89         if(root==null){
 90             root = child;
 91             System.out.println(root.data);
 92         }
 93         else 
 94             if(root.data>child.data){
 95                 System.out.print(root.data+"<--");//在root左边插入
 96                 root.left = insert(root.left, child);
 97             }
 98             else{
 99                 System.out.print(root.data+"-->"); //在root右边插入
100                 root.right = insert(root.right,child);
101             }    
102         return root;
103     }
104     
105     //节点的数据结构
106     private static class Node {
107         public int data;
108         public Node left;   //指向左子树
109         public Node right;  //指向右子树
110         public Node() {
111             super();
112             // TODO Auto-generated constructor stub
113         }
114         public Node(int data, Node left, Node right) {
115             super();
116             this.data = data;
117             this.left = left;
118             this.right = right;
119         }
120     }
121 
122 }

运行结果:

 建树过程(a<--b表示在a左边插入b;a-->b表示在a右边插入b):
10
10<--5
10-->12
10<--5<--4
10<--5-->7
这是所有的路径:
10-->5-->7
10-->12
 
 
原文地址:https://www.cnblogs.com/wuzetiandaren/p/4249910.html