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

 

posted on 2016-01-16 15:37  BillZ  阅读(659)  评论(0编辑  收藏  举报

导航