二叉树的下一个节点java实现
剑指offer面试题——八=
题目描述: 给定一课二叉树和其中一个节点,如何找出中序遍历的下一个节点?树中的节点除了有两个分别指向左右子节点的指针,还有一个指向父节点的指针
a
/ \
b c
/ \ / \
d e f g
/ \
h i
1.思路图解
首先根据二叉树的中序遍历的性质,左根右,所以遍历到当前节点时,他的左子树已经遍历完毕,所以可以将二叉树的下一个节点分为三种情况
-
一个节点有右子树
当一个节点有右子树,根据左根右的特性,这个节点的左边和自己已经遍历完了,那么当他遍历右子树的第一个节点时,以上图为例,a节点的右子树第一个节点为c,那么遍历c节点的时候右会根据中序遍历的特点,向左遍历,直到左子树为空
所以当一个节点有右子树的时候,他的下一个节点就是右子树的最左子节点 -
一个节点没有右子树,并且他为父节点的左子节点
如果一个节点没有右子树,并且为它父节点的左子节点,那么这种情况很好理解,以上图为列子,d节点,他没有右子树,并且他为父节点b的左子节点,所以当d遍历完毕时,说明以b为节点的左子树遍历完了
所以d节点的的下一个节点就是b节点 -
一个节点没有右子树,并且为它父节点的右子节点
如果一个节点没右右子树,并且为它父节点的右子节点,那么情况稍微复杂,根据中序遍历的特点,当一个节点为它父节点的右子节点,那么它的父节点已经遍历完毕,所以此时要沿着他的父节点一直向上找,直到找到一个节点为它父节点的左子节点,以上图为例,i节点为e节点的右子节点,并且没有右子树,所以i节点的父节点e已经遍历过,并且e节点为父节点b的右子节点,所以b节点也已经遍历过,但是b节点为a节点的左子节点,此时,以b为根节点的a的左子树已经全部遍历完了
所以i节点的下一个节点就是a节点
2.代码实现
package datasturct;
public class BinaryTreeNextNode {
public static void main(String[] args) {
TreeNode1 nodeA = new TreeNode1('a');
TreeNode1 nodeB = new TreeNode1('b');
TreeNode1 nodeC = new TreeNode1('c');
TreeNode1 nodeD = new TreeNode1('d');
TreeNode1 nodeE = new TreeNode1('e');
TreeNode1 nodeF = new TreeNode1('f');
TreeNode1 nodeG = new TreeNode1('g');
TreeNode1 nodeH = new TreeNode1('h');
TreeNode1 nodeI = new TreeNode1('i');
connectTreeNodes(nodeA,nodeB,nodeC);
connectTreeNodes(nodeB,nodeD,nodeE);
connectTreeNodes(nodeE,nodeH,nodeI);
connectTreeNodes(nodeC,nodeF,nodeG);
nodeA.infixOrder();
TreeNode1 next = getNext(nodeI);
System.out.println(next);
}
public static TreeNode1 getNext (TreeNode1 node1){
if (node1 == null){
return null;
}
TreeNode1 nodeNext = null;
//当右子节点不为空是,node1的下一个节点就是右子节点的最左子节点
if(node1.right != null){
TreeNode1 rightNode = node1.right;
while (rightNode.left != null){
rightNode = rightNode.left;
}
nodeNext = rightNode;
}else if(node1.parent != null){
//当右子节点为空,并且父节点不为空时
TreeNode1 currentNode = node1;
TreeNode1 parentNode = node1.parent;
//循环向上遍历,直到找到一个节点为他父节点的左子节点,
while (parentNode != null && currentNode == parentNode.right){
currentNode = parentNode;
//parentNode.parent就是要找的下一个节点
parentNode = parentNode.parent;
}
nodeNext = parentNode;
}
return nodeNext;
}
public static void connectTreeNodes(TreeNode1 parent,TreeNode1 left,TreeNode1 right){
if(parent != null){
parent.left = left;
parent.right = right;
if(left != null){
left.parent = parent;
}
if(right != null){
right.parent = parent;
}
}
}
}
class TreeNode1{
char value;
TreeNode1 left;
TreeNode1 right;
TreeNode1 parent;
public TreeNode1(char value) {
this.value = value;
}
public char getValue() {
return value;
}
public void setValue(char value) {
this.value = value;
}
public TreeNode1 getLeft() {
return left;
}
public void setLeft(TreeNode1 left) {
this.left = left;
}
public TreeNode1 getRight() {
return right;
}
public void setRight(TreeNode1 right) {
this.right = right;
}
public TreeNode1 getParent() {
return parent;
}
public void setParent(TreeNode1 parent) {
this.parent = parent;
}
@Override
public String toString() {
return "TreeNode1{" +
"value=" + value +
'}';
}
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}
System.out.println(this);
if(this.right != null){
this.right.infixOrder();
}
}
}