This repository acts as a personal archive for my solutions to EdX course *Data Structures and Software Design* from PennX.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.0 KiB

  1. import java.util.Stack;
  2. import java.util.List;
  3. public class BinarySearchTree<E extends Comparable<E>> {
  4. class Node {
  5. E value;
  6. Node leftChild = null;
  7. Node rightChild = null;
  8. Node(E value) {
  9. this.value = value;
  10. }
  11. @Override
  12. public boolean equals(Object obj) {
  13. if ((obj instanceof BinarySearchTree.Node) == false)
  14. return false;
  15. @SuppressWarnings("unchecked")
  16. Node other = (BinarySearchTree<E>.Node)obj;
  17. return other.value.compareTo(value) == 0 &&
  18. other.leftChild == leftChild && other.rightChild == rightChild;
  19. }
  20. }
  21. protected Node root = null;
  22. protected void visit(Node n) {
  23. System.out.println(n.value);
  24. }
  25. public boolean contains(E val) {
  26. return contains(root, val);
  27. }
  28. protected boolean contains(Node n, E val) {
  29. if (n == null) return false;
  30. if (n.value.equals(val)) {
  31. return true;
  32. } else if (n.value.compareTo(val) > 0) {
  33. return contains(n.leftChild, val);
  34. } else {
  35. return contains(n.rightChild, val);
  36. }
  37. }
  38. public boolean add(E val) {
  39. if (root == null) {
  40. root = new Node(val);
  41. return true;
  42. }
  43. return add(root, val);
  44. }
  45. protected boolean add(Node n, E val) {
  46. if (n == null) {
  47. return false;
  48. }
  49. int cmp = val.compareTo(n.value);
  50. if (cmp == 0) {
  51. return false; // this ensures that the same value does not appear more than once
  52. } else if (cmp < 0) {
  53. if (n.leftChild == null) {
  54. n.leftChild = new Node(val);
  55. return true;
  56. } else {
  57. return add(n.leftChild, val);
  58. }
  59. } else {
  60. if (n.rightChild == null) {
  61. n.rightChild = new Node(val);
  62. return true;
  63. } else {
  64. return add(n.rightChild, val);
  65. }
  66. }
  67. }
  68. public boolean remove(E val) {
  69. return remove(root, null, val);
  70. }
  71. protected boolean remove(Node n, Node parent, E val) {
  72. if (n == null) return false;
  73. if (val.compareTo(n.value) == -1) {
  74. return remove(n.leftChild, n, val);
  75. } else if (val.compareTo(n.value) == 1) {
  76. return remove(n.rightChild, n, val);
  77. } else {
  78. if (n.leftChild != null && n.rightChild != null){
  79. n.value = maxValue(n.leftChild);
  80. remove(n.leftChild, n, n.value);
  81. } else if (parent == null) {
  82. root = n.leftChild != null ? n.leftChild : n.rightChild;
  83. } else if (parent.leftChild == n){
  84. parent.leftChild = n.leftChild != null ? n.leftChild : n.rightChild;
  85. } else {
  86. parent.rightChild = n.leftChild != null ? n.leftChild : n.rightChild;
  87. }
  88. return true;
  89. }
  90. }
  91. protected E maxValue(Node n) {
  92. if (n.rightChild == null) {
  93. return n.value;
  94. } else {
  95. return maxValue(n.rightChild);
  96. }
  97. }
  98. /*********************************************
  99. *
  100. * IMPLEMENT THE METHODS BELOW!
  101. *
  102. *********************************************/
  103. // Method #1.
  104. public Node findNode(E val) {
  105. Node node = this.root;
  106. if(val == null) return null;
  107. while(!node.value.equals(val)){
  108. if(node.value.compareTo(val) > 0) node = node.leftChild;
  109. else node = node.rightChild;
  110. if(node == null) return null;
  111. }
  112. return node;
  113. }
  114. // Method #2.
  115. protected int depth(E val) { // Basically the same method as findNode
  116. int depth = 0;
  117. Node node = this.root;
  118. if(val == null) return -1;
  119. while(!node.value.equals(val)){
  120. if(node.value.compareTo(val) > 0) node = node.leftChild;
  121. else node = node.rightChild;
  122. if(node == null) return -1;
  123. depth++;
  124. }
  125. return depth;
  126. }
  127. // Method #3.
  128. protected int height(E val) {
  129. int leftHeight, rightHeight;
  130. Node node = this.findNode(val);
  131. if(val == null) return -1;
  132. if(node == null) return -1;
  133. if(node.leftChild == null && node.rightChild == null) return 0;
  134. leftHeight = node.leftChild == null ? 0 : this.height(node.leftChild.value);
  135. rightHeight = node.rightChild == null ? 0 : this.height(node.rightChild.value);
  136. return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
  137. }
  138. // Method #4.
  139. protected boolean isBalanced(Node n) {
  140. if(n == null) return false;
  141. if(this.findNode(n.value) == null) return false;
  142. int diff = Math.abs(this.height(n.leftChild == null ? null : n.leftChild.value) - this.height(n.rightChild == null ? null : n.rightChild.value));
  143. return diff == 0 || diff == 1;
  144. }
  145. // Method #5. .
  146. public boolean isBalanced() {
  147. Stack<Node> explored = new Stack<Node>();
  148. explored.push(this.root);
  149. Node node;
  150. while(!explored.isEmpty()){
  151. node = explored.pop();
  152. if(!this.isBalanced(node)) return false;
  153. if(node.leftChild != null){
  154. explored.push(node.leftChild);
  155. }
  156. if(node.rightChild != null){
  157. explored.push(node.rightChild);
  158. }
  159. }
  160. return true;
  161. }
  162. }