题目:给定一颗二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左、右子节点的指针,还有一个指向父节点的指针。
/**
* @version 1.0
* @Author zjay
* @Date: 2021/8/18$
* @Description: TODO
* 题目:给定一颗二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?
* 树中的节点除了有两个分别指向左、右子节点的指针,还有一个指向父节点的指针。
* 思路分析:
* 关键点1:中序遍历的下一个节点,因为是中序遍历,所以节点的左子树必为节点的上一个节点,不同考虑节点的左子树
* 接下来分情况讨论:
* 1.节点没有右子树:
* 若为父节点的左子节点,则其下一个节点为父节点;
* 若为父节点的右子节点,则下一个节点为该节点的父节点的父节点。。不为右子树的节点的父节点,比如 9的下一个节点是1,
* 9为5的右子节点,5为2的右子节点,2不为1的右子节点,所以9的下一个为2的父子节点1.
* 2. 节点有右子树
* 下一个节点为右子树的最左节点。
*
*/
public class Test8_BinaryTreeGetNext {
public static void main(String[] args) {
// 构建二叉树
BinaryTreeNode node1 = new BinaryTreeNode(1);
BinaryTreeNode node2 = new BinaryTreeNode(2);
BinaryTreeNode node3 = new BinaryTreeNode(3);
BinaryTreeNode node4 = new BinaryTreeNode(4);
BinaryTreeNode node5 = new BinaryTreeNode(5);
BinaryTreeNode node6 = new BinaryTreeNode(6);
BinaryTreeNode node7 = new BinaryTreeNode(7);
BinaryTreeNode node8 = new BinaryTreeNode(8);
BinaryTreeNode node9 = new BinaryTreeNode(9);
node1.left = node2;
node1.right = node3;
node1.parent = null;
node2.left = node4;
node2.right = node5;
node2.parent = node1;
node3.left = node6;
node3.right = node7;
node3.parent = node1;
node4.parent = node2;
node5.left = node8;
node5.right = node9;
node5.parent = node2;
node6.parent = node3;
node7.parent = node3;
node8.parent = node5;
node9.parent = node5;
// 中序遍历结果
//infixOrder(node1);
//获取输入节点的下一个节点
BinaryTreeNode nextNode = getNext(node1); // 有右子树节点测试
BinaryTreeNode nextNode1 = getNext(node6); // 没有右子树节点测试,为父节点的左子节点
BinaryTreeNode nextNode2 = getNext(node7); // 没有右子树节点测试,为父节点的右子节点
if(nextNode2 != null) {
System.out.println(nextNode2.val);
} else {
System.out.println("null");
}
}
public static void infixOrder(BinaryTreeNode head){
if(head.left != null) {
infixOrder(head.left);
}
System.out.println(head.val);
if(head.right != null) {
infixOrder(head.right);
}
}
/**
* 寻找二叉树中指定节点的中序遍历下一个节点
* @param node 输入指定的节点
* @return 返回指定节点的下一个节点
*/
public static BinaryTreeNode getNext(BinaryTreeNode node) {
// 非法输入判断
if(node == null) {
return null;
}
BinaryTreeNode targetNode = null;
if(node.right != null) { // 节点右子树不为空
targetNode = node.right;
while (targetNode.left != null) {
targetNode = targetNode.left;
}
} else { // 节点没有右子树
if(node.parent == null) { //该节点为根节点,且没有右子树,下一个为Null
return null;
}else {
if (node.parent.left == node) { // 节点为父节点的左子节点
return node.parent;
} else { // 节点为父节点的右子节点
targetNode = node;
//此处targetNode.parent != null放面前,不满足不用判断后面的条件
//若targetNode.parent此时为空,即7节点开始,null没有左子节点,会空指针异常
while (targetNode.parent != null && targetNode.parent.left != targetNode ) {
targetNode = targetNode.parent;
}
if(targetNode.parent != null) { // 循环结束后,target为其父节点的左子节点
targetNode = targetNode.parent;
} else {
return null;
}
}
}
}
return targetNode;
}
}
//二叉树节点类
class BinaryTreeNode{
int val;
BinaryTreeNode left;
BinaryTreeNode right;
BinaryTreeNode parent;
public BinaryTreeNode(int val) {
this.val = val;
}
}