思路:给出N,有三条路可以走,L,R,P
向L走:不会向L走(中序遍历先左子树再根然后到右子树,既然都到根N了,就不会返回到左子树L)
如果N的R!=null:返回右子树的第一个结点
如果N的R==null,
且N是P的左子树:
返回P
否则,且N不是P的左子树:
一直往父亲结点走,
直到是某个结点左子树
代码示例:
package com.sise.recursion;
public class InOrder {
/*
* 中序遍历的下一个结点
*/
public TreeNode next(TreeNode node) {
if(node==null){
return null;
}
if(node.getRighe()!=null){//R!=null:
return first(node.getRighe());//返回右子树的第一个结点
}else{//如果N的R==null,
//当node.getParent()==null时,不能往父结点走
while(node.getParent()!=null&&node.getParent().getRighe()==node){ //且不N是P的左子树(是右子树):
node = node.getParent();//一直往父亲结点走,
}
//while的条件取反:node.getParent()==null,仍然返回node.getParent()=null。
//node是它父亲的左子树,返回p=node.getParent()。
return node.getParent();//返回P
}
}
/*
* 返回中序遍历的第一个结点
*/
public TreeNode first(TreeNode node) {
if(node==null){
return null;
}
TreeNode curNode=node;
while (curNode.getLeft()!=null) {
curNode=curNode.getLeft();
}
return curNode;
}
public void traverse(TreeNode root) {
for(TreeNode node=first(root);
node!=null;
node=next(node)){
System.out.print(node.getValue());
}
System.out.println();
}
public static void main(String[] args) {
TreeCreator creator=new TreeCreator();
InOrder inOrder=new InOrder();
TreeNode sampleTree=creator.createSampleTree();
//从中序遍历的第一个结点开始
//封装为traverse()
// for (TreeNode node =inOrder.first(sampleTree);
// node!=null;
// node=inOrder.next(node)){
// System.out.print(node.getValue());
// }
// System.out.println();
inOrder.traverse(sampleTree);
inOrder.traverse(creator.creataTree("", ""));
inOrder.traverse(creator.creataTree("A", "A"));
inOrder.traverse(creator.creataTree("AB", "AB"));
inOrder.traverse(creator.creataTree("ABCD", "DCBA"));
inOrder.traverse(creator.creataTree("ABCD", "ABCD"));
}
}
package com.sise.recursion;
/*
* 建树
*/
public class TreeCreator {
public TreeNode createSampleTree() {
TreeNode root=new TreeNode('A');
root.setLeft(new TreeNode('B'));
root.getLeft().setLeft(new TreeNode('D'));
root.getLeft().setRighe(new TreeNode('E'));
root.getLeft().getRighe().setLeft(new TreeNode('G'));
root.setRighe(new TreeNode('C'));
root.getRighe().setRighe(new TreeNode('F'));
return root;
}
public TreeNode creataTree(String preOrder,String inOrder) {
if(preOrder.isEmpty()){//判断特殊情况
return null;
}
char rootValue=preOrder.charAt(0);
int rootIndex=inOrder.indexOf(rootValue);
TreeNode root=new TreeNode(rootValue);
root.setLeft(
creataTree(
preOrder.substring(1,1+rootIndex),
inOrder.substring(0,rootIndex)));
root.setRighe(
creataTree(
preOrder.substring(1+rootIndex),
inOrder.substring(1+rootIndex)));
return root;
}
}
package com.sise.recursion;
public class TreeNode {
private final char value;
private TreeNode left;
private TreeNode righe;
private TreeNode parent;
public TreeNode (char value) {
this.value=value;
this.left=null;
this.righe=null;
this.parent=null;
}
public TreeNode getLeft() {
return left;
}
public void setLeft(TreeNode left) {
this.left = left;
if(this.left!=null){
this.left.setParent(this);//使用private函数来维护复杂数据结构
}
}
public TreeNode getRighe() {
return righe;
}
public void setRighe(TreeNode righe) {
this.righe = righe;
if(this.righe!=null){
this.righe.setParent(this);//使用private函数来维护复杂数据结构
}
}
public char getValue() {
return value;
}
public TreeNode getParent() {
return parent;
}
//使用private函数来维护复杂数据结构
private void setParent(TreeNode parent) {
this.parent = parent;
}
}
运行结果:
总结:
分情况讨论
注意null指针
使用private函数来维护复杂数据结构