Description

剑指 Offer 36. 二叉搜索树与双向链表

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

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

剑指Offer 36. 二叉搜索树与双向链表 - 图1

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

剑指Offer 36. 二叉搜索树与双向链表 - 图2

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

Solution

递归中序遍历版本

  1. class Node {
  2. public int val;
  3. public Node left;
  4. public Node right;
  5. public Node() {}
  6. public Node(int _val) {
  7. val = _val;
  8. }
  9. public Node(int _val,Node _left,Node _right) {
  10. val = _val;
  11. left = _left;
  12. right = _right;
  13. }
  14. };
  15. */
  16. class Solution {
  17. Node res = null;
  18. Node pre = null;
  19. public Node treeToDoublyList(Node root) {
  20. if (root == null)
  21. return root;
  22. inRecursion(root);
  23. res.left = pre;
  24. pre.right = res;
  25. return res;
  26. }
  27. private void inRecursion(Node node ){
  28. if (node == null)
  29. return;
  30. inRecursion(node.left);
  31. if (res == null){
  32. res = node;
  33. pre = node;
  34. }else {
  35. pre.right = node;
  36. node.left = pre;
  37. pre = node;
  38. }
  39. inRecursion(node.right);
  40. }
  41. }

循环中序遍历版本

  1. /*
  2. // Definition for a Node.
  3. class Node {
  4. public int val;
  5. public Node left;
  6. public Node right;
  7. public Node() {}
  8. public Node(int _val) {
  9. val = _val;
  10. }
  11. public Node(int _val,Node _left,Node _right) {
  12. val = _val;
  13. left = _left;
  14. right = _right;
  15. }
  16. };
  17. */
  18. class Solution {
  19. public Node treeToDoublyList(Node root) {
  20. if (root == null) return root;
  21. Stack<Node> stack = new Stack<>();
  22. Node fast = root, slow = null,res = null;
  23. while (fast != null){
  24. stack.push(fast);
  25. fast = fast.left;
  26. }
  27. res = stack.peek();
  28. while (!stack.isEmpty() || fast != null){
  29. if (fast != null){
  30. stack.push(fast);
  31. fast = fast.left;
  32. }else {
  33. fast = stack.pop();
  34. if (slow != null){
  35. fast.left = slow;
  36. slow.right = fast;
  37. }
  38. slow = fast;
  39. fast = fast.right;
  40. }
  41. }
  42. res.left = slow;
  43. slow.right = res;
  44. return res;
  45. }
  46. }