题目

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

1.中序遍历+数组

  1. /**
  2. * // Definition for a Node.
  3. * function Node(val,left,right) {
  4. * this.val = val;
  5. * this.left = left;
  6. * this.right = right;
  7. * };
  8. */
  9. /**
  10. * @param {Node} root
  11. * @return {Node}
  12. */
  13. var treeToDoublyList = function (root) {
  14. // 二叉搜索树 中序遍历是递增队列
  15. // 记录 调整
  16. const store = []
  17. const mid_search = (root) => {
  18. if (!root) {
  19. return
  20. }
  21. mid_search(root.left)
  22. store.push(root)
  23. mid_search(root.right)
  24. }
  25. mid_search(root)
  26. const head = new Node()
  27. head.right = store[0]
  28. for (let i = 0; i < store.length; i++) {
  29. if (i === 0) {
  30. store[i].left = store[store.length - 1]
  31. } else {
  32. store[i].left = store[i - 1]
  33. }
  34. if (i === store.length - 1) {
  35. store[i].right = store[0]
  36. } else {
  37. store[i].right = store[i + 1]
  38. }
  39. }
  40. return head.right
  41. };

2.原地解法
中序遍历
在遍历右节点时,先记录中间节点(根节点),这样可以形成双向链表

  1. /**
  2. * // Definition for a Node.
  3. * function Node(val,left,right) {
  4. * this.val = val;
  5. * this.left = left;
  6. * this.right = right;
  7. * };
  8. */
  9. /**
  10. * @param {Node} root
  11. * @return {Node}
  12. */
  13. var treeToDoublyList = function (root) {
  14. // 中序遍历 + 记录前一个节点
  15. const mid_s = (root) => {
  16. if (!root) {
  17. return
  18. }
  19. mid_s(root.left)
  20. if (pre) {
  21. root.left = pre
  22. pre.right = root
  23. } else {
  24. head = root
  25. }
  26. pre = root
  27. mid_s(root.right)
  28. }
  29. if (!root) return root
  30. let head
  31. let pre = null
  32. mid_s(root)
  33. pre.right = head
  34. head.left = pre
  35. return head
  36. };