package offer;
public class TreeNextDNode {
public static void main(String[] args) {
PTreeNode tree=new PTreeNode().constructPTree();//构建树
TreeNextDNode treeNextDNode=new TreeNextDNode();
PTreeNode node=treeNextDNode.findANodeByData(tree,'g');//找到指定值的节点
PTreeNode resultNode=treeNextDNode.findLDRNext(node);//找到该节点的中序遍历 下一个值
if(resultNode==null)
System.out.println("No next node!");
else
System.out.println("Next node's data is "+resultNode.getData());
}
//中序遍历的下一个节点
PTreeNode findLDRNext(PTreeNode node)
{
if(node.getRight()!=null)//有右子树,下一节点在右子树上
{
return findEndLeft(node.getRight());
}
else if(node.getParent()!=null)//没有右子树但是有父节点,下一节点可能在父节点中
{
return findFirstParentInRight(node);
}
else//既没有右子树也没有父节点,则没有下一个节点
return null;
}
//向下查找,肯定是右子树上的最左侧节点
PTreeNode findEndLeft(PTreeNode node){
while(node!=null)
{
if(node.getLeft()!=null)node=node.getLeft();
else
break;
}
return node;
}
//向上查找,查找作为左子树的第一个父节点,也就是查找第一个在自己右侧的父节点
PTreeNode findFirstParentInRight(PTreeNode node){
while(node.getParent()!=null && (node==node.getParent().getRight()))
{//本节点一直在父节点的右子树上,节点向上回退
node=node.getParent();
}
//如果退出循环后,节点父节点不为空且自己处在父节点的左子树上就返回父节点
if(node.getParent()!=null && node==node.getParent().getLeft())return node.getParent();
return null;
}
//假设节点的值在树中没有重复,根据每个节点的元素值递归找到树中的对应节点并返回
PTreeNode findANodeByData(PTreeNode tree,char data)
{
PTreeNode left = null,right=null;
//当前节点值与指定值相同
if(tree.getData()==data)
{
return tree;
}
//左子树不为空,查找左子树
if(tree.getLeft()!=null)
{
left=findANodeByData(tree.getLeft(), data);
}
//右子树不为空查找右子树
if(tree.getRight()!=null)
{
right=findANodeByData(tree.getRight(), data);
}
//返回查到的节点,如果没有则返回null
return (left==null)?(right==null?null:right):left;
}
}
//树节点并可以调用constructPTree 构建一个树,如下
/**
* a
* / \
* b c
* / \ / \
* d e f g
* / \
* h i
*/
class PTreeNode {
char data;
PTreeNode left;
PTreeNode right;
PTreeNode parent;
PTreeNode constructPTree()
{
PTreeNode head=new PTreeNode();
PTreeNode left=new PTreeNode();
PTreeNode right=new PTreeNode();
PTreeNode tmp=right;
PTreeNode headResult=head;
head.data='a';
head.setLeft(left);
head.setRight(right);
head.setParent(null);
left.setData('b');
left.setParent(head);
right.setData('c');
right.setParent(head);
head=left;
left=new PTreeNode();
right=new PTreeNode();
head.setLeft(left);
head.setRight(right);
left.setData('d');
right.setData('e');
left.setParent(head);
right.setParent(head);
left.setLeft(null);
left.setRight(null);
head=right;
left=new PTreeNode();
right=new PTreeNode();
head.setLeft(left);
head.setRight(right);
left.setData('h');
right.setData('i');
head=tmp;
left=new PTreeNode();
right=new PTreeNode();
head.setLeft(left);
head.setRight(right);
left.setData('f');
left.setParent(head);
right.setData('g');
right.setParent(head);
return headResult;
}
public char getData() {
return data;
}
public void setData(char data) {
this.data = data;
}
public PTreeNode getLeft() {
return left;
}
public void setLeft(PTreeNode left) {
this.left = left;
}
public PTreeNode getRight() {
return right;
}
public void setRight(PTreeNode right) {
this.right = right;
}
public PTreeNode getParent() {
return parent;
}
public void setParent(PTreeNode parent) {
this.parent = parent;
}
}