思路一(菜鸡版)
使用数组存储先序遍历的各node(先序遍历得到的是从小到大的顺序)。然后循环给数组里的每个node赋上新的left和right。
代码
/**
* // Definition for a Node.
* function Node(val,left,right) {
* this.val = val;
* this.left = left;
* this.right = right;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var treeToDoublyList = function(root) {
var arr = [];
var dfs = function(root) {
if(root) {
dfs(root.left);
arr.push(root);
dfs(root.right);
}
}
dfs(root);
var head = arr[0];
for(let i = 0; i < arr.length; i++) {
arr[i].right = arr[(i + 1)%(arr.length)];
arr[i].left = arr[(i -1 + arr.length) % arr.length];
}
return head;
};
思路二
思路参考自:【JS】剑指 Offer 36. 二叉搜索树与双向链表
- 二叉搜索树的节点的 左树值 < 节点值 < 右树值
- 题目中说“head” 表示指向链表中有最小元素的节点。所以我们从左->中->右的顺序遍历二叉搜索树
- 深度优先搜索dfs,我们用pre记录前一个节点,head记录头结点
- 判断pre节点是否存在
- 若pre节点不存在时,说明是第一个节点,head指向当前node,if (pre == null) head = node
- 若pre节点存在时,说明不是第一个节点,我们可以将前一个节点的后继节点指向当前node,if (pre) pre.right = node
- 因为是从小到大遍历的,所以知道当前节点的前一个节点,因此
当当前节点node的前驱节点指向pre,node.left = pre, - 在下次循环前,将pre指向当前node,pre = node
- 遍历完整个二叉树,我们需要将首尾节点进行串联,此时head指向头结点,pre指向尾节点,因此
将尾结点pre的后继节点指向头结点head,pre.right = head
将头结点head的前驱节点指向尾结点pre,head.left = pre
代码
/**
* // Definition for a Node.
* function Node(val,left,right) {
* this.val = val;
* this.left = left;
* this.right = right;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var treeToDoublyList = function(root) {
var arr = [];
var pre = null;
var head = null;
var dfs = function(cur) {
if(!cur) return;
dfs(cur.left);
if(pre == null) head = cur;
else pre.right = cur;
cur.left = pre;
pre = cur;
dfs(cur.right);
}
if(!root) return null;
dfs(root);
head.left = pre;
pre.right = head;
return head;
};