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
这道题有很多种问法:
-
由BST构造一个新的无环双向链表。
-
由BST构造一个新的有环双向链表。
-
将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。
non-cycle:
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
* Definition for Doubly-ListNode.
* public class DoublyListNode {
* int val;
* DoublyListNode next, prev;
* DoublyListNode(int val) {
* this.val = val;
* this.next = this.prev = null;
* }
* }
*/
//用来记录list的状态,prev是之前访问的node,head是第一个node
class State {
DoublyListNode prev;
DoublyListNode head;
State(DoublyListNode prev, DoublyListNode head) {
this.prev = prev;
this.head = head;
}
State() {
this.prev = null;
this.head = null;
}
}
// 每次新建一个节点,将它指向前一个节点,前一个节点指向它
public class Solution {
/**
* @param root: The root of tree
* @return: the head of doubly list node
*/
public DoublyListNode bstToDoublyList(TreeNode root) {
if(root == null) {
return null;
}
// DoublyListNode prev = null, head = null;
State state = new State();
helper(root, state);
return state.head;
}
//helper函数的定义是:将root为根的树变成doubly-linked list然后与state.prev相连接
private void helper(TreeNode root, State state) {
if(root == null) {
return;
}
helper(root.left, state);
DoublyListNode node = new DoublyListNode(root.val);
node.prev = state.prev;
if(state.prev != null) {
state.prev.next = node;
}else {
state.head = node;
}
state.prev = node;
helper(root.right, state);
}
}
cycle:
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
* Definition for Doubly-ListNode.
* public class DoublyListNode {
* int val;
* DoublyListNode next, prev;
* DoublyListNode(int val) {
* this.val = val;
* this.next = this.prev = null;
* }
* }
*/
//用来记录list的状态,prev是之前访问的node,head是第一个node
class State {
DoublyListNode prev;
DoublyListNode head;
State(DoublyListNode prev, DoublyListNode head) {
this.prev = prev;
this.head = head;
}
State() {
this.prev = null;
this.head = null;
}
}
// 每次新建一个节点,将它指向前一个节点,前一个节点指向它
public class Solution {
/**
* @param root: The root of tree
* @return: the head of doubly list node
*/
public DoublyListNode bstToDoublyList(TreeNode root) {
if(root == null) {
return null;
}
// DoublyListNode prev = null, head = null;
State state = new State();
helper(root, state);
return state.head;
}
private void helper(TreeNode root, State state) {
if(root == null) {
return;
}
helper(root.left, state);
DoublyListNode node = new DoublyListNode(root.val);
node.prev = state.prev;
if(state.prev != null) {
state.prev.next = node;
}else {
state.head = node;
}
state.head.prev = node;
node.next = state.head;
state.prev = node;
helper(root.right, state);
}
}
时间复杂度为O(n),n为树中节点的个数。