题目
- 给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
![]()
法一、前序遍历+数组存值
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],cur=list[i]
//确定节点的连接
prev.left=null
prev.right=cur
}
};
//前序遍历的具体实现
const preorderTraversal=(root,list)=>{
if(root === null) return
list.push(root)
preorderTraversal(root.left,list)
preorderTraversal(root.right,list)
}
法二、找前驱节点
var flatten = function(root) {
// 将当前节点初始化为根节点
let curr = root;
// 当当前节点不为空时,继续遍历
while (curr !== null) {
// 如果当前节点的左子树不为空
if (curr.left !== null) {
// 保存左子树的根节点
const next = curr.left;
// 初始化前驱节点为左子树的根节点
let predecessor = next;
// 找到左子树的最右节点
while (predecessor.right !== null) {
predecessor = predecessor.right; // 移动到右子节点
}
// 将原右子树连接到左子树的最右节点
predecessor.right = curr.right;
// 清空当前节点的左子树
curr.left = null;
// 将左子树的根节点移到当前节点的右侧
curr.right = next;
}
// 当前节点的左子树为空:移动到当前节点的右子节点,继续处理
curr = curr.right;
}
};