java之二叉树和为某一值的路径
2015-06-17 16:48
633 查看
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径,从树的根结点开始往下一直到叶子结点所经过的结点形成一条路径。二叉树结点定义如下:
class BiTree {
int value;
BiTree lchild, rchild;
public BiTree(int value) {
this.value = value;
lchild = null;
rchild = null;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BiTree getLchild() {
return lchild;
}
public void setLchild(BiTree lchild) {
this.lchild = lchild;
}
public BiTree getRchild() {
return rchild;
}
public void setRchild(BiTree rchild) {
this.rchild = rchild;
}
}
分析:用前序遍历的方式访问到某一结点时,我们把该节点添加到路径上,并累计该结点的值。如果该节点是叶子节点并且路径中的值的和刚好等于输入的整数,则当前路径符合要求,我们把它打印出来。如果当前结点不是叶子结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到它的父结点。因此我们函数退出之前要在路径上删除当前结点并减去当前结点的值,一确保返回父节点时的路径刚好是从根结点到父结点的路径。实际上是栈,因为路径要与递归调用状态一致。
下面为完整代码:
package Tree;
import java.util.Iterator;
import java.util.Stack;
public class FindPathMian {
public static void findpath(BiTree root, int expectedSum) {
if (root == null)
return;
Stack<Integer> path = new Stack<Integer>();
int currentSum = 0;
findpath(root, expectedSum, path, currentSum);
}
public static void findpath(BiTree root, int expectedSum,
Stack<Integer> path, int currentSum) {
currentSum += root.value;
path.push(root.value);
boolean isLeaf = root.lchild == null && root.rchild == null;
if (currentSum == expectedSum && isLeaf) {
System.out.println("A path is found:");
Iterator<Integer> it = path.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
if (root.lchild != null)
findpath(root.lchild, expectedSum, path, currentSum);
if (root.rchild != null)
findpath(root.rchild, expectedSum, path, currentSum);
path.pop();
}
public static BiTree ConstructCore(int[] preOder, int[] inOder,
int startpreOder, int startinOder, int endpreOder, int endinOder) {
int rootValue = preOder[startpreOder];
BiTree root = new BiTree(rootValue);
// 在中序遍历中找到根节点
int mid = startinOder;
while (mid <= endinOder && inOder[mid] != rootValue)
++mid;
int leftLength = mid - startinOder;
int leftPreOderEnd = startpreOder + leftLength;
if (leftLength > 0) {
// 构建左子树
root.setLchild(ConstructCore(preOder, inOder, startpreOder + 1,
startinOder, leftPreOderEnd, mid - 1));
}
if (leftLength < endpreOder - startpreOder) {
// 构建右子树
root.setRchild(ConstructCore(preOder, inOder, leftPreOderEnd + 1,
mid + 1, endpreOder, endinOder));
}
return root;
}
public static void main(String[] args) {
int preOder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int inOder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
BiTree trr = ConstructCore(preOder, inOder, 0, 0, 7, 7);
findpath(trr, 14);
}
}
结果为:
A path is found:
1,2,4,7
class BiTree {
int value;
BiTree lchild, rchild;
public BiTree(int value) {
this.value = value;
lchild = null;
rchild = null;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BiTree getLchild() {
return lchild;
}
public void setLchild(BiTree lchild) {
this.lchild = lchild;
}
public BiTree getRchild() {
return rchild;
}
public void setRchild(BiTree rchild) {
this.rchild = rchild;
}
}
分析:用前序遍历的方式访问到某一结点时,我们把该节点添加到路径上,并累计该结点的值。如果该节点是叶子节点并且路径中的值的和刚好等于输入的整数,则当前路径符合要求,我们把它打印出来。如果当前结点不是叶子结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到它的父结点。因此我们函数退出之前要在路径上删除当前结点并减去当前结点的值,一确保返回父节点时的路径刚好是从根结点到父结点的路径。实际上是栈,因为路径要与递归调用状态一致。
下面为完整代码:
package Tree;
import java.util.Iterator;
import java.util.Stack;
public class FindPathMian {
public static void findpath(BiTree root, int expectedSum) {
if (root == null)
return;
Stack<Integer> path = new Stack<Integer>();
int currentSum = 0;
findpath(root, expectedSum, path, currentSum);
}
public static void findpath(BiTree root, int expectedSum,
Stack<Integer> path, int currentSum) {
currentSum += root.value;
path.push(root.value);
boolean isLeaf = root.lchild == null && root.rchild == null;
if (currentSum == expectedSum && isLeaf) {
System.out.println("A path is found:");
Iterator<Integer> it = path.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
if (root.lchild != null)
findpath(root.lchild, expectedSum, path, currentSum);
if (root.rchild != null)
findpath(root.rchild, expectedSum, path, currentSum);
path.pop();
}
public static BiTree ConstructCore(int[] preOder, int[] inOder,
int startpreOder, int startinOder, int endpreOder, int endinOder) {
int rootValue = preOder[startpreOder];
BiTree root = new BiTree(rootValue);
// 在中序遍历中找到根节点
int mid = startinOder;
while (mid <= endinOder && inOder[mid] != rootValue)
++mid;
int leftLength = mid - startinOder;
int leftPreOderEnd = startpreOder + leftLength;
if (leftLength > 0) {
// 构建左子树
root.setLchild(ConstructCore(preOder, inOder, startpreOder + 1,
startinOder, leftPreOderEnd, mid - 1));
}
if (leftLength < endpreOder - startpreOder) {
// 构建右子树
root.setRchild(ConstructCore(preOder, inOder, leftPreOderEnd + 1,
mid + 1, endpreOder, endinOder));
}
return root;
}
public static void main(String[] args) {
int preOder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int inOder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
BiTree trr = ConstructCore(preOder, inOder, 0, 0, 7, 7);
findpath(trr, 14);
}
}
结果为:
A path is found:
1,2,4,7
相关文章推荐
- java时间戳
- java时间戳
- java中Pattern.compile函数的相关解释
- Java最著名的开源项目
- 【failed to create java virtual machine】 解决方案
- 关于java.lang.UnsatisfiedLinkError的小案例
- eclipse 中文乱码问题解决
- eclipse+android配置SDK+ADT
- intellij在jdk1.7和1.8的字体问题
- java项目war打包和解压
- Java Dns Cache Manipulator
- LeetCode20 Valid Parentheses的java 题解
- struts的modelDriver模型驱动运用
- Java中socket传送中文乱码问题解决方法
- 通过dom4j进行数据读取xml文件进行数据的读取操作
- JAVA串口开发学习笔记1
- Eclipse 中设置JVM 内存及JVM监控调优
- java获取当前年月日
- Java仿文库的基本方法(openoffice+swftools+flexPaper)
- jdk1.8新特性