Convert Binary Search Tree to Doubly Linked List
Question:
Convert a binary search tree to doubly linked list with in-order traversal.
Example:
Given a binary search tree:
4
/ \
2 5
/ \
1 3
return 1<->2<->3<->4<->5
Analysis:
这道题有很多种问法:
1. 由BST构造一个新的无环双向链表。
2. 由BST构造一个新的有环双向链表。
3. 将BST改造成一个双向链表。
问题1:中序遍历BST,每访问一个新的tree node,构造一个新的list node。将新的list node的prev指针指向之前访问的list node,然后将之前访问的list node的next指针指向新的list node。因为要记录之前访问的list node的信息,我们创建一个state对象,state.prev记录之前访问的list node,state.head记录链表的头节点。如何判断头节点很简单,如果state.prev等于null,说明当前节点之前没有节点了,那么该节点就是头节点。helper函数的定义:以root为根节点的BST构造一个双向链表,并将新链表链接到state.prev节点上去,同时记录头节点和最后访问的节点的信息。
问题2:在问题1的基础上,每往链表中添加一个新节点,将头节点的prev指针指向该新节点,然后新节点的next指针指向头节点。当链表构造完,整个链表自然就是一个循环链表。
问题3:和之前的问题几乎一模一样,因为tree node有两个指针(left,right),list node同样有两个指针(prev,next)。遍历BST的时候,每访问一个tree node,将它的left指针指向之前访问的tree node,将之前访问的tree node的right指针指向当前节点。注意:不可以修改当前访问的tree node的right指针,因为我们需要通过right指针找到下一个访问的tree node。
Code:
non-cycle:
1 /** 2 * Definition of TreeNode: 3 * public class TreeNode { 4 * public int val; 5 * public TreeNode left, right; 6 * public TreeNode(int val) { 7 * this.val = val; 8 * this.left = this.right = null; 9 * } 10 * } 11 * Definition for Doubly-ListNode. 12 * public class DoublyListNode { 13 * int val; 14 * DoublyListNode next, prev; 15 * DoublyListNode(int val) { 16 * this.val = val; 17 * this.next = this.prev = null; 18 * } 19 * } 20 */ 21 22 //用来记录list的状态,prev是之前访问的node,head是第一个node 23 class State { 24 DoublyListNode prev; 25 DoublyListNode head; 26 27 State(DoublyListNode prev, DoublyListNode head) { 28 this.prev = prev; 29 this.head = head; 30 } 31 32 State() { 33 this.prev = null; 34 this.head = null; 35 } 36 } 37 38 // 每次新建一个节点,将它指向前一个节点,前一个节点指向它 39 public class Solution { 40 /** 41 * @param root: The root of tree 42 * @return: the head of doubly list node 43 */ 44 public DoublyListNode bstToDoublyList(TreeNode root) { 45 if(root == null) { 46 return null; 47 } 48 49 // DoublyListNode prev = null, head = null; 50 State state = new State(); 51 helper(root, state); 52 53 return state.head; 54 } 55 56 //helper函数的定义是:将root为根的树变成doubly-linked list然后与state.prev相连接 57 private void helper(TreeNode root, State state) { 58 if(root == null) { 59 return; 60 } 61 62 helper(root.left, state); 63 64 DoublyListNode node = new DoublyListNode(root.val); 65 node.prev = state.prev; 66 if(state.prev != null) { 67 state.prev.next = node; 68 }else { 69 state.head = node; 70 } 71 72 state.prev = node; 73 helper(root.right, state); 74 } 75 }
cycle:
1 /** 2 * Definition of TreeNode: 3 * public class TreeNode { 4 * public int val; 5 * public TreeNode left, right; 6 * public TreeNode(int val) { 7 * this.val = val; 8 * this.left = this.right = null; 9 * } 10 * } 11 * Definition for Doubly-ListNode. 12 * public class DoublyListNode { 13 * int val; 14 * DoublyListNode next, prev; 15 * DoublyListNode(int val) { 16 * this.val = val; 17 * this.next = this.prev = null; 18 * } 19 * } 20 */ 21 22 //用来记录list的状态,prev是之前访问的node,head是第一个node 23 class State { 24 DoublyListNode prev; 25 DoublyListNode head; 26 27 State(DoublyListNode prev, DoublyListNode head) { 28 this.prev = prev; 29 this.head = head; 30 } 31 32 State() { 33 this.prev = null; 34 this.head = null; 35 } 36 } 37 38 // 每次新建一个节点,将它指向前一个节点,前一个节点指向它 39 public class Solution { 40 /** 41 * @param root: The root of tree 42 * @return: the head of doubly list node 43 */ 44 public DoublyListNode bstToDoublyList(TreeNode root) { 45 if(root == null) { 46 return null; 47 } 48 49 // DoublyListNode prev = null, head = null; 50 State state = new State(); 51 helper(root, state); 52 53 return state.head; 54 } 55 56 private void helper(TreeNode root, State state) { 57 if(root == null) { 58 return; 59 } 60 61 helper(root.left, state); 62 63 DoublyListNode node = new DoublyListNode(root.val); 64 node.prev = state.prev; 65 if(state.prev != null) { 66 state.prev.next = node; 67 }else { 68 state.head = node; 69 } 70 71 state.head.prev = node; 72 node.next = state.head; 73 state.prev = node; 74 helper(root.right, state); 75 } 76 }
Complexity:
时间复杂度为O(n),n为树中节点的个数。
参考:
https://github.com/JoyceeLee/Data_Structure/blob/master/Binary-Tree/Convert%20Binary%20Search%20Tree%20(BST)%20to%20Sorted%20Doubly-Linked%20List.java