@@ -13,8 +13,13 @@ class ThreadedBinaryNode<V extends Comparable>
1313
1414 /// Stores if [right] is a thread.
1515 bool rightIsThread;
16+
17+ ThreadedBinaryNode (this .value,
18+ {this .leftIsThread = true , this .rightIsThread = true });
1619}
1720
21+ enum _DeleteCase { twoChildren, oneChild, childless }
22+
1823/// A [BinaryTree] is threaded by making all [right] pointers that would
1924/// normally be null point to the in-order successor of the node
2025/// (if it exists), and all [left] pointers that would normally be null point
@@ -25,21 +30,213 @@ class ThreadedBinaryTree<V extends Comparable>
2530
2631 @override
2732 void add (V value) {
28- throw UnimplementedError ();
33+ ThreadedBinaryNode parent, node = root;
34+ var isPresent = false ;
35+
36+ while (node != null ) {
37+ if (node.value.compareTo (value) == 0 ) {
38+ isPresent = true ;
39+ break ;
40+ }
41+
42+ parent = node;
43+ if (node.value.compareTo (value) > 0 ) {
44+ if (! node.leftIsThread) {
45+ node = node.left;
46+ } else {
47+ break ;
48+ }
49+ } else if (! node.rightIsThread) {
50+ node = node.right;
51+ } else {
52+ break ;
53+ }
54+ }
55+
56+ if (! isPresent) {
57+ var newNode = ThreadedBinaryNode (value);
58+
59+ if (parent == null ) {
60+ root = newNode;
61+ } else if (parent.value.compareTo (value) > 0 ) {
62+ newNode.left = parent.left;
63+ newNode.right = parent;
64+ parent.leftIsThread = false ;
65+ parent.left = newNode;
66+ } else {
67+ newNode.left = parent;
68+ newNode.right = parent.right;
69+ parent.rightIsThread = false ;
70+ parent.right = newNode;
71+ }
72+ }
2973 }
3074
3175 @override
3276 void delete (V value) {
33- throw UnimplementedError ();
77+ ThreadedBinaryNode parent, node = root;
78+ var isPresent = false ;
79+
80+ while (node != null ) {
81+ if (node.value.compareTo (value) == 0 ) {
82+ isPresent = true ;
83+ break ;
84+ }
85+
86+ parent = node;
87+ if (node.value.compareTo (value) > 0 ) {
88+ if (! node.leftIsThread) {
89+ node = node.left;
90+ } else {
91+ break ;
92+ }
93+ } else if (! node.rightIsThread) {
94+ node = node.right;
95+ } else {
96+ break ;
97+ }
98+ }
99+
100+ if (isPresent) {
101+ if (! node.leftIsThread && ! node.rightIsThread) {
102+ // Node has 2 children.
103+ _delete (parent, node, _DeleteCase .twoChildren);
104+ } else if (! node.leftIsThread) {
105+ // Node has only a left child.
106+ _delete (parent, node, _DeleteCase .oneChild);
107+ } else if (! node.rightIsThread) {
108+ // Node has only a right child.
109+ _delete (parent, node, _DeleteCase .oneChild);
110+ } else {
111+ // Node is childless.
112+ _delete (parent, node, _DeleteCase .childless);
113+ }
114+ }
115+ }
116+
117+ void _delete (ThreadedBinaryNode parent, ThreadedBinaryNode node,
118+ _DeleteCase deleteCase) {
119+ switch (deleteCase) {
120+ case _DeleteCase .childless:
121+ if (parent == null ) {
122+ nullify ();
123+ } else if (node == parent.left) {
124+ parent.leftIsThread = true ;
125+ parent.left = node.left;
126+ } else {
127+ parent.rightIsThread = true ;
128+ parent.right = node.right;
129+ }
130+ break ;
131+
132+ case _DeleteCase .oneChild:
133+ var child = node.leftIsThread ? node.right : node.left;
134+
135+ if (parent == null ) {
136+ root = child;
137+ } else if (node == parent.left) {
138+ parent.left = child;
139+ } else {
140+ parent.right = child;
141+ }
142+
143+ var successor = _inOrderSuccessor (node);
144+ var predecessor = _inOrderPredecessor (node);
145+ if (! node.leftIsThread) {
146+ predecessor.right = successor;
147+ } else {
148+ if (! node.rightIsThread) {
149+ successor.left = predecessor;
150+ }
151+ }
152+ break ;
153+
154+ case _DeleteCase .twoChildren:
155+ ThreadedBinaryNode successor, parentSuccessor;
156+ parentSuccessor = node;
157+ successor = node.right;
158+
159+ while (successor.left != null ) {
160+ parentSuccessor = successor;
161+ successor = successor.left;
162+ }
163+
164+ node.value = successor.value;
165+
166+ if (successor.leftIsThread && successor.rightIsThread) {
167+ _delete (parentSuccessor, successor, _DeleteCase .childless);
168+ } else {
169+ _delete (parentSuccessor, successor, _DeleteCase .oneChild);
170+ }
171+ break ;
172+ }
34173 }
35174
36175 @override
37176 List <V > inOrder () {
38- throw UnimplementedError ();
177+ var result = < V > [];
178+ if (isEmpty) return result;
179+
180+ var node = root;
181+ while (! node.leftIsThread) {
182+ node = node.left;
183+ }
184+
185+ while (node.rightIsThread) {
186+ result.add (node.value);
187+ node = _inOrderSuccessor (node);
188+ }
189+ return result;
39190 }
40191
41192 @override
42193 List <V > preOrder () {
43- throw UnimplementedError ();
194+ var result = < V > [];
195+ if (isEmpty) return result;
196+
197+ var node = root;
198+ while (node != null ) {
199+ result.add (node.value);
200+ if (! node.leftIsThread) {
201+ node = node.left;
202+ } else if (! node.rightIsThread) {
203+ node = node.right;
204+ } else {
205+ while (node != null && node.rightIsThread) {
206+ node = node.right;
207+ }
208+
209+ if (node != null ) {
210+ node = node.right;
211+ }
212+ }
213+ }
214+ return result;
215+ }
216+
217+ ThreadedBinaryNode _inOrderSuccessor (ThreadedBinaryNode node) {
218+ if (node.rightIsThread) {
219+ return node.right;
220+ } else {
221+ node = node.right;
222+
223+ while (! node.leftIsThread) {
224+ node = node.left;
225+ }
226+ return node;
227+ }
228+ }
229+
230+ ThreadedBinaryNode _inOrderPredecessor (ThreadedBinaryNode node) {
231+ if (node.leftIsThread) {
232+ return node.left;
233+ } else {
234+ node = node.left;
235+
236+ while (! node.rightIsThread) {
237+ node = node.right;
238+ }
239+ return node;
240+ }
44241 }
45242}
0 commit comments