【剑指Offer】面试题36. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:

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

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
首先遍历左子树,找到最左 节点
pre == null的时候cur在①节点上,也就是最左节点,即双向链表的头节点。然后令pre = cur。
下一次cur在②节点上,pre是①节点,pre != null,添加边pre.right = cur,覆盖边 cur.left = pre

然后遍历右子树,cur来到③节点上,pre != null, pre.right = cur。然后cur.left = pre。更新pre的位置pre = cur。

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

浙公网安备 33010602011771号