Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.50 KB | None | 0 0
  1. package edu.hm.cs.katz.algdat.trees;
  2.  
  3. import java.util.LinkedList;
  4. import java.util.Queue;
  5. import java.util.function.Consumer;
  6.  
  7. /**
  8. * Class representing a binary tree storing only key values (like sets). This class does not provide
  9. * any operations changing the tree, as any dynamic operations have to be provided by the subclasses
  10. * adding additional restrictions.
  11. *
  12. * @author katz.bastian
  13. */
  14. public class BinaryTree<T> {
  15.  
  16. /** Root node of the tree, may be null for empty tree. */
  17. private TreeNode<T> root;
  18.  
  19. /**
  20. * Constructor to define from an existing structure of {@link TreeNode}s.
  21. *
  22. * @param root root node
  23. */
  24. BinaryTree(TreeNode<T> root) {
  25. this.root = root;
  26. }
  27.  
  28. /**
  29. * Constructor to define an empty tree.
  30. */
  31. public BinaryTree() {
  32. // intentionally left blank.
  33. }
  34.  
  35. /* Query operations */
  36.  
  37. /**
  38. * @return number of nodes in the tree.
  39. */
  40. int getSize() {
  41. return getSize(root);
  42. }
  43.  
  44. /**
  45. * Helper method. Recursively calculates the number of nodes in the (sub)tree.
  46. *
  47. * @param node tree node
  48. * @return number of nodes in the subtree of the given node
  49. */
  50. private int getSize(TreeNode<T> node) {
  51. if (node == null) {
  52. return 0;
  53. }
  54. return 1 + getSize(node.left) + getSize(node.right);
  55. }
  56.  
  57. /**
  58. * Calculates the height of the tree. By definition, the empty tree has height 0, a tree with
  59. * one node has height 1.
  60. *
  61. * @return the height of the tree.
  62. */
  63. int getHeight() {
  64. return getHeight(root);
  65. }
  66.  
  67. /**
  68. * Helper method. Recursively calculates the height of a (sub)tree.
  69. *
  70. * @param node tree node
  71. * @return height of the subtree of the given node.
  72. */
  73. private int getHeight(TreeNode<T> node) {
  74. if (node == null) {
  75. return 0;
  76. }
  77. return 1 + Math.max(getHeight(node.left), getHeight(node.right));
  78. }
  79.  
  80. /**
  81. * @return number of leaves of the tree.
  82. */
  83. int getLeafCount() {
  84. // TODO: Aufgabe 13.1
  85. return getLeafCount(root);
  86. }
  87.  
  88. private int getLeafCount(TreeNode<T> node) {
  89. if (node == null) {
  90. return 0;
  91. }
  92. if (node.left == null && node.right == null) {
  93. return 1;
  94. }
  95. return getLeafCount(node.left) + getLeafCount(node.right);
  96. }
  97.  
  98. /**
  99. * @param element key
  100. * @return true if the key is contained in the tree, false otherwise.
  101. */
  102. boolean contains(T element) {
  103. // TODO: Aufgabe 13.2
  104. return contains(root, element);
  105. }
  106.  
  107. private boolean contains(TreeNode<T> node, T element) {
  108. if (node == null) {
  109. return false;
  110. }
  111. return node.data.equals(element) || contains(node.left, element)
  112. || contains(node.right, element);
  113. }
  114.  
  115. /**
  116. * Vertauscht in allen Knoten linken und rechten Teilbaum.
  117. */
  118. void invert() {
  119. // TODO: Aufgabe 13.4
  120. invertTree(root);
  121. }
  122.  
  123. private TreeNode<T> invertTree(TreeNode<T> node) {
  124. if (node == null) {
  125. return null;
  126. }
  127. TreeNode right = invertTree(node.right);
  128. TreeNode left = invertTree(node.left);
  129. node.left = right;
  130. node.right = left;
  131. return node;
  132. }
  133.  
  134. /**
  135. * Entfernt alle Blätter, die den übergebenen Wert enthalten
  136. *
  137. * @param element Wert
  138. */
  139. void removeLeaves(T element) {
  140. // TODO: Aufgabe 13.5
  141. deleteLeaf(root, element);
  142. }
  143.  
  144. private TreeNode<T> deleteLeaf(TreeNode<T> node, T key) {
  145. if (node == null) return node;
  146. if (contains(node.left, key)) {
  147. node.left = deleteLeaf(node.left, key);
  148. } else if (contains(node.right, key)) {
  149. node.right = deleteLeaf(node.right, key);
  150. }
  151. else {
  152. if (node.left == null)
  153. return node.right;
  154. else if (node.right == null)
  155. return node.left;
  156. }
  157.  
  158. return node;
  159. }
  160.  
  161. /* Traversal operations. */
  162.  
  163. /**
  164. * Applies an operation on all nodes in the tree in level-order.
  165. *
  166. * @param operation operation to be applied to all nodes
  167. */
  168. void visitNodesBfs(Consumer<T> operation) {
  169. Queue<TreeNode<T>> bfsQueue = new LinkedList<>();
  170.  
  171. // Initial wartet nur die Wurzel
  172. bfsQueue.add(root);
  173.  
  174. // Solange noch Knoten warten
  175. while (!bfsQueue.isEmpty()) {
  176.  
  177. // Nimm nächsten Knoten
  178. TreeNode<T> node = bfsQueue.remove();
  179. if (node != null) {
  180. // Bearbeite Knoten
  181. operation.accept(node.data);
  182.  
  183. // Füge Kinder in Schlange ein
  184. bfsQueue.add(node.left);
  185. bfsQueue.add(node.right);
  186. }
  187. }
  188. }
  189.  
  190. /**
  191. * Applies an operation on all nodes in the tree in pre-, in- or post-order, i.e. in any order
  192. * produces by depth-first-search.
  193. *
  194. * @param operation operation to be applied to all nodes
  195. * @param order defines in which order the operation is applied to the node and the subtrees
  196. */
  197. void visitNodesDfs(Consumer<T> operation, DfsOrder order) {
  198. visitNodesDfs(root, operation, order);
  199. }
  200.  
  201. /**
  202. * Helper method to recursively apply an operation on all nodes in the tree in pre-, in- or
  203. * post-order, i.e. in any order produces by depth-first-search.
  204. *
  205. * @param node tree node
  206. * @param operation operation to be applied to all nodes in the subtree of the given node
  207. * @param order defines in which order the operation is applied to the node and the subtrees
  208. */
  209. private void visitNodesDfs(TreeNode<T> node, Consumer<T> operation, DfsOrder order) {
  210. if (node != null) {
  211.  
  212. // start with the node in pre-order
  213. if (order == DfsOrder.PREORDER) {
  214. operation.accept(node.data);
  215. }
  216.  
  217. // recursively visit nodes in left subtree
  218. visitNodesDfs(node.left, operation, order);
  219.  
  220. if (order == DfsOrder.INORDER) {
  221. operation.accept(node.data);
  222. }
  223.  
  224. visitNodesDfs(node.right, operation, order);
  225.  
  226. if (order == DfsOrder.POSTORDER) {
  227. operation.accept(node.data);
  228. }
  229. }
  230. }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement