2
2
3
3
import java .util .ArrayDeque ;
4
4
import java .util .ArrayList ;
5
+ import java .util .Deque ;
5
6
import java .util .HashSet ;
6
7
import java .util .List ;
7
8
import java .util .Random ;
20
21
*
21
22
* @author Justin Wetherell <phishman3579@gmail.com>
22
23
*/
23
- public class BinarySearchTree <T extends Comparable <T >> {
24
+ @ SuppressWarnings ("unchecked" )
25
+ public class BinarySearchTree <T extends Comparable <T >> implements ITree <T > {
24
26
25
27
private int modifications = 0 ;
26
28
@@ -41,8 +43,7 @@ public enum DepthFirstSearchOrder {
41
43
/**
42
44
* Default constructor.
43
45
*/
44
- public BinarySearchTree () {
45
- }
46
+ public BinarySearchTree () { }
46
47
47
48
/**
48
49
* Constructor with external Node creator.
@@ -52,12 +53,9 @@ public BinarySearchTree(INodeCreator<T> creator) {
52
53
}
53
54
54
55
/**
55
- * Add value to the tree. Tree can contain multiple equal values.
56
- *
57
- * @param value
58
- * T to add to the tree.
59
- * @return True if successfully added to tree.
56
+ * {@inheritDoc}
60
57
*/
58
+ @ Override
61
59
public boolean add (T value ) {
62
60
Node <T > nodeAdded = this .addValue (value );
63
61
return (nodeAdded != null );
@@ -116,14 +114,11 @@ protected Node<T> addValue(T value) {
116
114
}
117
115
118
116
/**
119
- * Does the tree contain the value.
120
- *
121
- * @param value
122
- * T to locate in the tree.
123
- * @return True if tree contains value.
117
+ * {@inheritDoc}
124
118
*/
119
+ @ Override
125
120
public boolean contains (T value ) {
126
- Node <T > node = getNode (value );
121
+ Node <T > node = getNode (( T ) value );
127
122
return (node != null );
128
123
}
129
124
@@ -284,15 +279,12 @@ protected Node<T> getLeast(Node<T> startingNode) {
284
279
}
285
280
286
281
/**
287
- * Remove first occurrence of value in the tree.
288
- *
289
- * @param value
290
- * T to remove from the tree.
291
- * @return True if value was removed from the tree.
282
+ * {@inheritDoc}
292
283
*/
293
- public boolean remove (T value ) {
284
+ @ Override
285
+ public T remove (T value ) {
294
286
Node <T > nodeToRemove = this .removeValue (value );
295
- return (nodeToRemove != null );
287
+ return (( nodeToRemove != null )? nodeToRemove . id : null );
296
288
}
297
289
298
290
/**
@@ -304,11 +296,21 @@ public boolean remove(T value) {
304
296
*/
305
297
protected Node <T > removeValue (T value ) {
306
298
Node <T > nodeToRemoved = this .getNode (value );
299
+ if (nodeToRemoved != null ) removeNode (nodeToRemoved );
300
+ return nodeToRemoved ;
301
+ }
302
+
303
+ /**
304
+ * Remove the node using a replacement
305
+ *
306
+ * @param nodeToRemoved
307
+ * Node<T> to remove from the tree.
308
+ */
309
+ protected void removeNode (Node <T > nodeToRemoved ) {
307
310
if (nodeToRemoved != null ) {
308
311
Node <T > replacementNode = this .getReplacementNode (nodeToRemoved );
309
312
replaceNodeWithNode (nodeToRemoved , replacementNode );
310
313
}
311
- return nodeToRemoved ;
312
314
}
313
315
314
316
/**
@@ -413,22 +415,19 @@ protected void replaceNodeWithNode(Node<T> nodeToRemoved, Node<T> replacementNod
413
415
}
414
416
415
417
/**
416
- * Get number of nodes in the tree.
417
- *
418
- * @return Number of nodes in the tree.
418
+ * {@inheritDoc}
419
419
*/
420
+ @ Override
420
421
public int size () {
421
422
return size ;
422
423
}
423
424
424
425
/**
425
- * Validate the tree for all Binary Search Tree invariants.
426
- *
427
- * @return True if tree is valid.
426
+ * {@inheritDoc}
428
427
*/
428
+ @ Override
429
429
public boolean validate () {
430
- if (root == null )
431
- return true ;
430
+ if (root == null ) return true ;
432
431
return validateNode (root );
433
432
}
434
433
@@ -466,7 +465,6 @@ protected boolean validateNode(Node<T> node) {
466
465
*
467
466
* @return breath first search sorted array representing the tree.
468
467
*/
469
- @ SuppressWarnings ("unchecked" )
470
468
public T [] getBFS () {
471
469
Queue <Node <T >> queue = new ArrayDeque <Node <T >>();
472
470
T [] values = (T []) new Comparable [size ];
@@ -500,7 +498,6 @@ public T[] getLevelOrder() {
500
498
*
501
499
* @return in-order sorted array representing the tree.
502
500
*/
503
- @ SuppressWarnings ("unchecked" )
504
501
public T [] getDFS (DepthFirstSearchOrder order ) {
505
502
Set <Node <T >> added = new HashSet <Node <T >>(2 );
506
503
T [] nodes = (T []) new Comparable [size ];
@@ -582,6 +579,14 @@ public T[] getSorted() {
582
579
return getDFS (DepthFirstSearchOrder .inOrder );
583
580
}
584
581
582
+ /**
583
+ * {@inheritDoc}
584
+ */
585
+ @ Override
586
+ public java .util .Collection <T > toCollection () {
587
+ return (new JavaCompatibleBinarySearchTree <T >(this ));
588
+ }
589
+
585
590
/**
586
591
* {@inheritDoc}
587
592
*/
@@ -674,4 +679,102 @@ private static <T extends Comparable<T>> String getString(Node<T> node, String p
674
679
return builder .toString ();
675
680
}
676
681
}
682
+
683
+ private static class JavaCompatibleBinarySearchTree <T extends Comparable <T >> extends java .util .AbstractCollection <T > {
684
+
685
+ protected BinarySearchTree <T > tree = null ;
686
+
687
+ public JavaCompatibleBinarySearchTree (BinarySearchTree <T > tree ) {
688
+ this .tree = tree ;
689
+ }
690
+
691
+ /**
692
+ * {@inheritDoc}
693
+ */
694
+ @ Override
695
+ public boolean add (T value ) {
696
+ return tree .add (value );
697
+ }
698
+
699
+ /**
700
+ * {@inheritDoc}
701
+ */
702
+ @ Override
703
+ public boolean remove (Object value ) {
704
+ return (tree .remove ((T )value )!=null );
705
+ }
706
+
707
+ /**
708
+ * {@inheritDoc}
709
+ */
710
+ @ Override
711
+ public boolean contains (Object value ) {
712
+ return tree .contains ((T )value );
713
+ }
714
+
715
+ /**
716
+ * {@inheritDoc}
717
+ */
718
+ @ Override
719
+ public int size () {
720
+ return tree .size ();
721
+ }
722
+
723
+ /**
724
+ * {@inheritDoc}
725
+ */
726
+ @ Override
727
+ public java .util .Iterator <T > iterator () {
728
+ return (new BinarySearchTreeIterator <T >(this .tree ));
729
+ }
730
+
731
+ private static class BinarySearchTreeIterator <C extends Comparable <C >> implements java .util .Iterator <C > {
732
+
733
+ private BinarySearchTree <C > tree = null ;
734
+ private BinarySearchTree .Node <C > last = null ;
735
+ private Deque <BinarySearchTree .Node <C >> toVisit = new ArrayDeque <BinarySearchTree .Node <C >>();
736
+
737
+ protected BinarySearchTreeIterator (BinarySearchTree <C > tree ) {
738
+ this .tree = tree ;
739
+ if (tree .root !=null ) toVisit .add (tree .root );
740
+ }
741
+
742
+ /**
743
+ * {@inheritDoc}
744
+ */
745
+ @ Override
746
+ public boolean hasNext () {
747
+ if (toVisit .size ()>0 ) return true ;
748
+ return false ;
749
+ }
750
+
751
+ /**
752
+ * {@inheritDoc}
753
+ */
754
+ @ Override
755
+ public C next () {
756
+ while (toVisit .size ()>0 ) {
757
+ // Go thru the current nodes
758
+ BinarySearchTree .Node <C > n = toVisit .pop ();
759
+
760
+ // Add non-null children
761
+ if (n .lesser !=null ) toVisit .add (n .lesser );
762
+ if (n .greater !=null ) toVisit .add (n .greater );
763
+
764
+ // Update last node (used in remove method)
765
+ last = n ;
766
+ return n .id ;
767
+ }
768
+ return null ;
769
+ }
770
+
771
+ /**
772
+ * {@inheritDoc}
773
+ */
774
+ @ Override
775
+ public void remove () {
776
+ tree .removeNode (last );
777
+ }
778
+ }
779
+ }
677
780
}
0 commit comments