彪码野郎

  • 首页

  • 分类

  • 归档

二叉树的前序后继节点

发表于 2019-09-22 分类于 数据结构与算法 阅读次数:

题目

给定一种新的二叉树节点如下:

1
2
3
4
5
6
7
8
9
10
public static class Node {
public int value;
public Node left;
public Node right;
public Node parent;

public Node(int data) {
this.value = data;
}
}

该结构比普通二叉树节点多了一个指向父节点的parent指针。

假设用这种节点组成的二叉树,树中每个节点的parent都正确地指向自己的父节点(头节点的parent指向null)。

现在给定某个节点node,请实现返回node的后继节点的函数。

  • 前驱节点和后继节点的概念

思路

拿到题目我们应该观察一下数据状况,中序遍历的特点是什么?

  • 以某一节点作为根,应先先遍历并输出其左子树(包括子孙那些),再输出自身,最后遍历并输出其右子树(包括子孙那些)。

简单来说就是左中右

  • 前驱和后继的是十分相似的,这里我们提供后继的思路,前驱的思路作为练习自行完成。(后面代码前驱后继都有,可以对照一下)

后继节点

我们可以把目标节点分成两种情况

  • 若当前节点拥有右子树,则其右子树最左的节点为前驱节点,因为中序遍历左中右,你当前作为中,你的后继节点必然是右(右的最左先哦)。
  • 若当前节点没有右子树,那就把你自己当作是某棵子树的最右部分,寻找是哪一代先辈把你所在的子树作为左子树(也就是找哪个节点把目标节点作为左子树的最右的节点)

文字描述可能比较抽象,下面看下具体的代码实现。

实现

后继节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static Node getSuccessorNode(Node node) {

if(node == null) return null;

//若有右子树,则表明自身是中
if(node.right != null) {
//找右子树中最左的那个
return getMostLeft(node.right);
}else {
//把自己当作子树中最右的那个吧

Node parent = node.parent;
//往上一层一层找,只要找到某个祖先节点把你所在的子树当左子树就停,若找不到则表明是整棵树最右的节点
while(parent != null && parent.left != node) {
node = parent;
parent = node.parent;
}

return parent;
}

}

public static Node getMostLeft(Node node) {

if(node == null) return node;

while(node.left != null) {
node = node.left;
}
return node;
}

前驱节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static Node getPredecessor(Node node) {

if(node == null) return null;

Node parent;
if(node.left != null) {
return getMostRight(node.left);
}else { //假设自己为最右的那个
parent = node.parent;
//不断往上检索,直到某个节点认你所在的子树作为右子树就停下
while(parent != null && parent.right != node) {
node = parent;
parent = node.parent;
}
}
return parent;
}

public static Node getMostRight(Node node) {

if(node == null) return node;

while(node.right != null) {
node = node.right;
}
return node;
}

测试方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//中序遍历:4,2,5,1,6,3,7
public static void main(String[] args) {
Node head = new Node(1);
head.parent = null;
head.left = new Node(2);
head.left.parent = head;
head.left.left = new Node(4);
head.left.left.parent = head.left;
head.left.right = new Node(5);
head.left.right.parent = head.left;
head.right = new Node(3);
head.right.parent = head;
head.right.left = new Node(6);
head.right.left.parent = head.right;
head.right.right = new Node(7);
head.right.right.parent = head.right;

//4
Node test = head.left.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
//2
test = head.left;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
//5
test = head.left.right;
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
//7
test = head.right.right;
System.out.println(test.value + " next: " + getSuccessorNode(test));
}
flex布局快速入门
序列化二叉树
  • 文章目录
  • 站点概览
Weapon

Weapon

40 日志
6 分类
4 标签
  1. 1. 题目
  2. 2. 思路
    1. 2.1. 后继节点
  3. 3. 实现
    1. 3.1. 后继节点
    2. 3.2. 前驱节点
    3. 3.3. 测试方法
© 2019 Weapon
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0