写在前面
最近想复习一下数据结构与算法相关的内容,找一些题来做一做。如有更好思路,欢迎指正。
一、场景描述
给定一个二叉树,原地将它展开为单链表。展开后的单链表应该同样使用TreeNode,其中right 子指针指向链表中下一个结点,而左子指针始终为null。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
二、具体步骤
1.环境说明
名称 | 说明 |
---|---|
IntelliJ IDEA | 2019.2 |
2.代码
以下为Java版本实现:
public class Lc114_flatten {
public static void main(String[] args) {
TreeNode n6 = new TreeNode(6);
TreeNode n5 = new TreeNode(5);
n5.right = n6;
TreeNode n4 = new TreeNode(4);
TreeNode n3 = new TreeNode(3);
TreeNode n2 = new TreeNode(2);
n2.left = n3;
n3.right = n4;
TreeNode root = new TreeNode(1);
root.left = n2;
root.right = n5;
flatten(root);
// 打印
while (root != null) {
System.out.println(root.val);
root = root.right;
}
}
/**
* 思路:
* 二叉树的展开为链表,顺序是先序遍历
* 且右子树放在左子树的最右结点上
*
* 1
* / \
* 2 5
* / \ \
* 3 4 6
*
*
* 1、将root根节点的右子树,插在左子树的最右节点的右子树上
* 1
* /
* 2
* / \
* 3 4
* \
* 5
* \
* 6
*
* 2、将root根节点的左子树插在root的右子树上,设置root的左子树为空
* 1
* / \
* null 2
* / \
* 3 4
* \
* 5
* \
* 6
*
* 3、将root变为root.right,继续下一轮循环,直到root为空
* 1
* / \
* null 2
* /
* 3
* \
* 4
* \
* 5
* \
* 6
*
* 1
* / \
* null 2
* / \
* null 3
* \
* 4
* \
* 5
* \
* 6
* ...
*
* while循环(root!=null)
* 如果 root.left=null, 则直接处理右子树 root = root.right
* 否则
* 首先找到左子树的最右结点,定义 pre = root.left, while(pre!=null) pre=pre.right,得到最右结点
* pre.right = root.right
* root.right = root.left
* root.left = null
*
* 进行下一次迭代处理,root = root.right
*
* @param root
*/
private static void flatten(TreeNode root) {
while (root != null) {
// 无左子树,一直是链表就不需要处理了
if (root.left == null) {
root = root.right;
} else {
// 找左子树的最右结点
TreeNode pre = root.left;
while (pre.right != null) {
pre = pre.right;
}
// 将root根节点的右子树,插在左子树的最右节点的右子树上
pre.right = root.right;
// 将root根节点的左子树插在root的右子树上,设置root的左子树为空
root.right = root.left;
// 处理左节点
root.left = null;
// 继续下一轮
root = root.right;
}
}
}
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
}
写在后面
如果本文内容对您有价值或者有启发的话,欢迎点赞、关注、评论和转发。您的反馈和陪伴将促进我们共同进步和成长。