题目描述
给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
输入:root = []
输出:[]
提示:
- 树中结点数在范围
[0, 2000]
内 -100 <= Node.val <= 100
import java.util.Stack;
public class Solution {
public void flatten(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
if(root!=null)
stack.push(root);
TreeNode prev = null;
while(!stack.isEmpty()){
TreeNode curr = stack.pop();
if(curr.right != null)
stack.push(curr.right);
if(curr.left != null)
stack.push(curr.left);
if(prev!=null){
prev.right = curr;
prev.left = null;
}
prev = curr;
}
}
}
思路
先审题,发现函数返回值为void,
所以说实际上是直接把root作为链表的头节点,链表通过右子节点连接
目标: 我不想直接新建一个链表,而是想把原来的二叉树修改为链表
辅助数据结构:
TreeNode prev //前序遍历的"后一个结点"
TreeNode curr //前序遍历的"前一个结点"
Stack<TreeNode> stack //用于循环实现前序遍历(这个栈不是递归转循环的递归栈!! 而是"逻辑栈")
逻辑: 为何需要curr与prev?
因为题目要求的"链表"实际上就是把 "二叉树前序遍历" 下的 后一个结点 作为 前一个结点 的右子节点
所以只需要 在循环中获取到 前一个结点prev 与 后一个结点curr , 并修改他们的连接方式即可(把curr作为prev的右子节点,把prev的左子节点置为null)
因为修改了连接方式的结点是 前序遍历概念中"已被访问过" 的结点,所以就算修改这些结点之间的连接方式也没关系(修改连接方式会破坏原有树结构)
二叉树前序遍历循环实现的图解
观察栈内的元素