LeetCode426 将二叉搜索树转化为排序的双向链表 & 剑指Offer 36 二叉搜索树与双向链表
题目
解题
一道换汤不换药的「二叉树中序遍历题」,对二叉树中序遍历比较陌生的建议先移步 LeetCode94 二叉树的中序遍历。
94 题是让按照中序遍历的顺序,以数组的形式输出节点值。本题不一样的地方在于是要构建一个 循环双向链表结构,left 指针等同于 prev 指针,right 指针等同于 next 指针,另外 首尾要相连接(记录 head 和 tail,最后连接它们)。
所以将节点 val 值加入数组的那步应该完成的任务变成:当前节点记为 A,A.left = 上一个加入的节点 B(如不为 null),B.right = A ; => 由此分析出需要记录上一个节点(正好符合 tail 指针记录的节点的含义)。因为在处理 A 时,A.left 即它的左子树已经被处理完毕,因而可以改变左指针,但是右子树会在 A 之后被遍历(二叉搜索树的性质),所以右指针要等处理下一个节点时才能被改变。
此外,首尾相连时要特别注意 空树 的情况。
解题一:递归
// javascript
var treeToDoublyList = function(root) {
if (root === null) return null; // 二叉搜索树为空
let head = null, tail = null; // 记录双向链表的 head 和 tail
const dfs = (root) => {
if (root === null) return;
// 先遍历左子树
dfs(root.left);
// 左子树遍历完后下一个该处理的是 root
if (head === null) {
// 如果头指针为空,说明 root 是头节点(第一个被处理的节点)
head = root;