文章目录
- 前言
- 什么是后继结点
- 什么是前驱结点
- 代码实现
- 查找某一结点的后继结点
- 思路
- 代码实现
- 图解
- 查找某一结点的前驱结点
- 思路
- 代码实现
- 图解
- 测试用例
- 运行结果
- 结语
前言
给定二叉树结点定义Node结构如下,其中parent结点指向当前Node结点的父结点,根结点指向null
:
private static class Node {
public int value;
public Node left;
public Node right;
/**
* 指向父结点,头结点指向null
*/
public Node parent;
public Node(int value) {
this.value = value;
}
}
什么是后继结点
定义:在二叉树的中序遍历的序列中,Node的下一个节点叫作Node的后继节点。
什么是前驱结点
定义:在二叉树的中序遍历的序列中,Node的前一个节点叫作Node的前驱节点。
代码实现
查找某一结点的后继结点
思路
根据中序遍历的顺序可以得出如下结论:
如果该结点存在右子树,则该结点对应的后继结点为其右子树上最左的结点;
如果该结点不存在右子树,向上查找,如果某个结点的parent结点的左子树等于该node结点,则此parent结点为后继结点
;
代码实现
/**
* 获取某个结点的后继结点
*
* @param node
* @return
*/
private static Node getSuccessorNode(Node node) {
if (node == null) {
return node;
}
if (node.right != null) {
//1.当node结点存在右子树,则后继结点为Node结点右子树最左边结点
return getLeftMost(node.right);
} else {
//当前Node结点没有右子树,则向上查找;
//某个结点的parent结点的左子树 == node结点,则此parent结点即为后继结点
Node parent = node.parent;
while (parent != null && parent.left != node) {
node = parent;
parent = node.parent;
}
return parent;
}
}
/**
* 获取某个结点最左结点
*
* @param node
* @return
*/
private static Node getLeftMost(Node node) {
if (node == null) {
return node;
}
while (node.left != null) {
node = node.left;
}
return node;
}
图解
查找某一结点的前驱结点
思路
与查找后继结点相类似,根据中序遍历顺序同样可以得出如下结论:
如果该结点存在左子树,则该结点对应的前驱结点为其左子树上最右的结点;
如果该结点不存在左子树,向上查找,如果某个结点的parent结点的右子树等于该node结点,则此parent结点为前驱结点
;
代码实现
/**
* 获取某一Node结点对应的前驱结点
*
* @param node
* @return
*/
private static Node getPrecursorNode(Node node) {
if (node == null) {
return node;
}
if (node.left != null) {
//1.当node结点存在左子树,则前驱结点为Node结点左子树最右边结点
return getRightMost(node.left);
} else {
//当前Node结点没有左子树,则向上查找;
//某个结点的parent结点的右子树 == node结点,则此parent结点即为后继结点
Node parent = node.parent;
while (parent != null && parent.right != node) {
node = parent;
parent = node.parent;
}
return parent;
}
}
/**
* 获取某一结点最右结点
*
* @param node
*/
private static Node getRightMost(Node node) {
if (node == null) {
return node;
}
while (node.right != null) {
node = node.right;
}
return node;
}
图解
测试用例
public static void main(String[] args) {
Node node = new Node(1);
node.parent = null;
node.left = new Node(2);
node.left.parent = node;
node.right = new Node(3);
node.right.parent = node;
node.left.left = new Node(4);
node.left.left.parent = node.left;
node.left.right = new Node(5);
node.left.right.parent = node.left;
node.left.right.left = new Node(6);
node.left.right.left.parent = node.left.right;
node.left.right.right = new Node(7);
node.left.right.right.parent = node.left.right;
Node target = node.left.right.left;
System.out.println(target.value + "的后继结点为:" + getSuccessorNode(target).value);
System.out.println(target.value + "的前驱结点为:" +getPrecursorNode(target).value);
}
运行结果
6的后继结点为:5
6的前驱结点为:2
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )