-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBinaryTreeToLinkedList.java
142 lines (118 loc) · 3.33 KB
/
BinaryTreeToLinkedList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
Given a Binary Tree, convert it to a (Circular) Doubly Linked List (In-Place) -- CDLL
-The left and right pointers in nodes are to be used as leftious and right pointers respectively in converted Circular Linked List.
-The order of nodes in List must be same as Inorder of the given Binary Tree.
-The first node of Inorder traversal must be head node of the Circular List.
*/
/*
Idea: recursion
1. convert left and right subtrees into two CDLL
2. connect left + root, connect that with right
3. need a function to merge two CDLL's
*/
import java.util.*;
class Node { // Circular doubly linked list - CDLL
int val;
Node left, right;
Node(int val) {
this.val = val;
}
}
public class BinaryTreeToLinkedList {
// ******************************************************************************
// Method 1: in-order traversal of BST
private static Node curr; // use a global variable to track current node
public static Node bstToList(Node root) {
Node dummy = new Node(0);
curr = dummy;
buildList(root);
// if circular:
// dummy.right.left = curr;
// curr.right = dummy.right;
return dummy.right;
}
private static void buildList(Node x) {
if (x == null) return;
buildList(x.left);
// connect curr to x and update curr
x.left = curr;
curr.right = x;
curr = x;
buildList(x.right);
}
// Iterative version
public static Node bstToListIterative(Node root) {
if (root == null) return null;
Node dummy = new Node(0);
Node curr = dummy, x = root;
Deque<Node> stack = new LinkedList<>();
while (x != null || !stack.isEmpty()) {
while (x != null) {
stack.push(x);
x = x.left;
}
// now x is null
x = stack.pop();
// connect curr to x
curr.right = x;
x.left = curr;
curr = x;
x = x.right;
}
return dummy.right;
}
// ******************************************************************************
// Method 2:
public static Node concatenate(Node l1, Node l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
// get the tail of list 1, and head of l2
l1.left.right = l2;
Node tail2 = l2.left;
l2.left = l1.left;
l1.left = tail2;
tail2.right = l1;
return l1;
}
public static Node treeToList(Node x) {
if (x == null) return null;
// recursive calls to left and right subtrees
// Note: create two NEW nodes for the left and right subtree's CDLLs
Node left = treeToList(x.left);
Node right = treeToList(x.right);
// make a Circular doubly linked list of the root node x
x.left = x;
x.right = x;
// concatenate three parts
return concatenate(concatenate(left, x), right);
}
public static void displayCircular(Node head) {
Node x = head;
do {
System.out.print(x.val + " ");
x = x.right;
} while (x != head);
}
public static void display(Node head) {
Node x = head;
while (x != null) {
System.out.print(x.val + " ");
x = x.right;
}
}
// ******************************************************************************
// test
public static void main(String[] args) {
Node[] nodes = new Node[6];
for (int i = 0; i < nodes.length; ++i) {
nodes[i] = new Node(i);
}
for (int i = 0; i < nodes.length / 2; ++i) {
nodes[i].left = nodes[2*i + 1];
if (2*i + 2 < nodes.length)
nodes[i].right = nodes[2*i + 2];
}
Node head = BinaryTreeToLinkedList.bstToListIterative(nodes[0]);
BinaryTreeToLinkedList.display(head);
}
}