二叉树展开为链表

二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例 1:

img

1
2
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

示例 2:

1
2
输入:root = []
输出:[]

示例 3:

1
2
输入:root = [0]
输出:[0]

解法一:递归

通过递归的方法,对树进行前序遍历,存入到list中,遍历list。

代码为:

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
33
34
35
36
37
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//递归
public void flatten(TreeNode root) {
List<TreeNode> list = new LinkedList<>();
//前序遍历
first(root,list);
int len = list.size();
//遍历list,展开为链表
for (int i = 1;i<len;i++){
TreeNode temp = list.get(i-1),right = list.get(i);
temp.left = null;
temp.right = right;
}
}
public void first(TreeNode root,List<TreeNode> list){
if (root!=null){
list.add(root);
first(root.left,list);
first(root.right,list);
}
}
}

解法二:迭代

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
33
34
35
36
37
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//迭代
public void flatten(TreeNode root) {
List<TreeNode> list = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
while (root!=null || !stack.isEmpty()){
while (root!=null){
list.add(root);
stack.add(root);
root = root.left;
}
root = stack.pop();
root = root.right;
}
int len = list.size();
for (int i = 1;i<len;i++){
TreeNode t = list.get(i-1),right = list.get(i);
t.left = null;
t.right = right;
}
}
}

解法三:在进行前序遍历的同时进行展开

image-20220910141634715

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
33
34
35
36
37
38
39
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//在进行前序遍历的同时进行展开
public void flatten(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
if (root!=null) stack.push(root);
TreeNode pre = null;
while (!stack.isEmpty()){
TreeNode current = stack.pop();
if (pre!=null){
pre.left = null;
pre.right = current;
}
if (current.right!=null){
TreeNode right = current.right;
stack.push(right);
}
if (current.left!=null){
TreeNode left = current.left;
stack.push(left);
}
pre = current;
}
}
}

解法四:不利用前序遍历,用寻找前驱节点

image-20220910142357003

image-20220910142523751

image-20220910142706338

image-20220910142715297

image-20220910142727633

​ 具体做法是,对于当前节点,如果其左子节点不为空,则在其左子树中找到最右边的节点,作为前驱节点,将当前节点的右子节点赋给前驱节点的右子节点,然后将当前节点的左子节点赋给当前节点的右子节点,并将当前节点的左子节点设为空。对当前节点处理结束后,继续处理链表中的下一个节点,直到所有节点都处理结束。

代码为:

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
33
34
35
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//不利用前序遍历,用寻找前驱节点
public void flatten(TreeNode root) {
TreeNode cur = root;
while (cur!=null){
if (cur.left!=null){
TreeNode left = cur.left;
TreeNode pre = left;
while (pre.right!=null){
pre = pre.right;
}
pre.right = cur.right;
cur.left = null;
cur.right = left;
}
cur = cur.right;
}

}
}

二叉树展开为链表
http://example.com/2022/09/10/二叉树展开为链表/
作者
zlw
发布于
2022年9月10日
许可协议