题目描述
给你二叉树的根结点 root,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null。 展开后的单链表应该与二叉树 先序遍历 顺序相同。
示例 1:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [0]
输出:[0]
思路&js代码
1、前序遍历(递归)
好理解
var flatten = function(root) {
const list = [];
preorderTraversal(root, list);
const size = list.length;
for (let i = 1; i < size; i++) {
const prev = list[i - 1], curr = list[i];
prev.left = null;
prev.right = curr;
}
};
const preorderTraversal = (root, list) => {
if (root != null) {
list.push(root);
preorderTraversal(root.left, list);
preorderTraversal(root.right, list);
}
}2、前序遍历(迭代)
var flatten = function(root) {
const list = [];
const stack = [];
let node = root;
while (node !== null || stack.length) {
while (node !== null) {
list.push(node);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
const size = list.length;
for (let i = 1; i < size; i++) {
const prev = list[i - 1], curr = list[i];
prev.left = null;
prev.right = curr;
}
};
3、头插法
采用头插法构建链表,也就是从节点 6 开始,在 6 的前面插入 5,在 5 的前面插入 4,依此类推。 为此,要按照 6→5→4→3→2→1 的顺序访问节点。如何遍历这棵树,才能实现这个顺序? 按照右子树 - 左子树 - 根的顺序 DFS 这棵树。 DFS 的同时,记录当前链表的头节点为 head。一开始 head 是空节点。
具体来说:
- 如果当前节点为空,返回。
- 递归右子树。
- 递归左子树。
- 把 root.left 置为空。
- 头插法,把 root 插在 head 的前面,也就是 root.right=head。
- 现在 root 是链表的头节点,把 head 更新为 root。
var flatten = function(root) {
let head = null;
function dfs(node) {
if (node === null) {
return;
}
dfs(node.right);
dfs(node.left);
node.left = null;
node.right = head; // 头插法,相当于链表的 node.next = head
head = node; // 现在链表头节点是 node
}
dfs(root);
};