当前位置:   article > 正文

数据结构——二叉树(Java 实现)_基于组合模式,使用 java 语言中实现一个二叉树的数据结构。

基于组合模式,使用 java 语言中实现一个二叉树的数据结构。

为什么使用二叉树?

1.在有序数据中插入数据项太慢;

2.在链表中查找太慢;

树既能向链表那样快速的插入和删除,又能像有序数组那样快速查找。

树的术语

路径:设想一下顺着连接节点的边从一个节点走到另一个节点,所经过的节点的顺序排列就称为“路径”。

根:树顶端的节点称为“根”。一棵树有且仅有一个根。

父节点,子节点。

叶节点:没有子节点的节点。

子树。

访问,遍历,层,关键字,二叉树,二叉搜索树。

二叉树和二叉搜索树区别联系?

二叉树指这样的树结构,它的每个结点的孩子数目最多为2个;二叉搜索树是一种二叉树,但是它有附加的一些约束条件,这些约束条件必须对每个结点都成立:

  • 结点node的左子树所有结点的值都小于node的值。
  • 结点node的右子树所有结点的值都大于node的值。
  • 结点node的左右子树同样都必须是二叉搜索树

 

  1. /**
  2. * Created by Zhans on 2018/9/4.
  3. * TreeApp
  4. * 二叉搜索树
  5. */
  6. /**
  7. * 节点类
  8. */
  9. class Node {
  10. public int iData;// 节点中的整数型数据(key)
  11. public double dData;//节点中的浮点型数据
  12. public Node leftChild;//该节点的左子节点
  13. public Node rightChild;//该节点的右子节点
  14. public void displayNode() {
  15. System.out.print('{');
  16. System.out.print(iData);
  17. System.out.print(", ");
  18. System.out.print(dData);
  19. System.out.print('}');
  20. }
  21. }
  22. /**
  23. * 树本身的类,由这个类实例化的对象含有所有的节点。它只有一个数据字段,一个表示根的Node变量
  24. */
  25. class Tree {
  26. private Node root;
  27. public Node find(int key) {//根据关键字key查找节点,假设不是空树
  28. Node current = root;
  29. while (current.iData != key) {
  30. if (current.iData < key)
  31. current = current.leftChild;
  32. else
  33. current = current.rightChild;
  34. if (current == null)
  35. return null;
  36. }
  37. return current;
  38. }
  39. public void insert(int id, double dd) {
  40. Node newNode = new Node();
  41. newNode.iData = id;
  42. newNode.dData = dd;
  43. if (root == null) //没有根节点
  44. root = newNode;
  45. else {
  46. Node current = root;
  47. Node parent;
  48. while (true) {
  49. parent = current;
  50. if (id < current.iData) {
  51. current = parent.leftChild;
  52. if (current == null) {
  53. parent.leftChild = newNode;
  54. return;
  55. }
  56. } else {
  57. current = parent.rightChild;
  58. if (current == null) {
  59. parent.rightChild = newNode;
  60. return;
  61. }
  62. }
  63. }
  64. }
  65. }
  66. public boolean delete(int key) {//删除关键词key所在的节点
  67. Node current = root;
  68. Node parent = root;
  69. boolean isLeftChild = true;
  70. while (current.iData != key) {//首先找到要删除的节点
  71. parent = current;
  72. if (key < current.iData) {
  73. isLeftChild = true;
  74. current = current.leftChild;
  75. } else {
  76. isLeftChild = false;
  77. current = current.rightChild;
  78. }
  79. if (current == null)
  80. return false;
  81. }
  82. if (current.leftChild == null && current.rightChild == null) {//要删除的节点为叶节点(没有子节点的节点)
  83. if (current == root) {
  84. root = null;
  85. } else if (isLeftChild) {
  86. parent.leftChild = null;
  87. } else {
  88. parent.rightChild = null;
  89. }
  90. } else if (current.rightChild == null) {//要删除的节点没有右子节点
  91. if (current == root)
  92. root = current.leftChild;
  93. else if (isLeftChild)
  94. parent.leftChild = current.leftChild;
  95. else
  96. parent.rightChild = current.leftChild;
  97. } else if (current.leftChild == null) {//要删除的节点没有左子节点
  98. if (current == root)
  99. root = current.rightChild;
  100. else if (isLeftChild)
  101. parent.leftChild = current.rightChild;
  102. else
  103. parent.rightChild = current.rightChild;
  104. } else {//要删除的节点有两个子节点,用该节点的后继节点代替此节点(后继节点:比该节点关键字值大的节点集合中最小的一个节点)
  105. Node successor = getSuccessor(current);
  106. if (current == root)
  107. root = successor;
  108. else if (isLeftChild)
  109. parent.leftChild = successor;
  110. else
  111. parent.rightChild = successor;
  112. successor.leftChild = current.leftChild;
  113. }
  114. return true;
  115. }
  116. private Node getSuccessor(Node delNode) {
  117. Node successorParent = delNode;
  118. Node successor = delNode;
  119. Node current = delNode.rightChild;
  120. while (current != null) {
  121. successorParent = successor;
  122. successor = current;
  123. current = current.leftChild;
  124. }
  125. if (successor != delNode.rightChild) {
  126. successorParent.leftChild = successor.rightChild;
  127. successor.rightChild = delNode.rightChild;
  128. }
  129. return successor;
  130. }
  131. /**
  132. * 中序遍历:
  133. * 1.调用自身访该节点的左子树
  134. * 2.访问节点
  135. * 3.调用自身访问该节点的右子树
  136. */
  137. private void inorderTraversal(Node localRoot) {
  138. if (localRoot != null) {
  139. inorderTraversal(localRoot.leftChild);
  140. System.out.print(localRoot.iData + " ");
  141. inorderTraversal(localRoot.rightChild);
  142. }
  143. }
  144. /**
  145. * 前序遍历:
  146. * 1.访问节点
  147. * 2.调用自身访该节点的左子树
  148. * 3.调用自身访问该节点的右子树
  149. */
  150. private void preorderTraversal(Node localRoot) {
  151. if (localRoot != null) {
  152. System.out.print(localRoot.iData + " ");
  153. preorderTraversal(localRoot.leftChild);
  154. preorderTraversal(localRoot.rightChild);
  155. }
  156. }
  157. /**
  158. * 后序遍历:
  159. * 1.调用自身访该节点的左子树
  160. * 2.调用自身访问该节点的右子树
  161. * 3.访问节点
  162. */
  163. private void postorderTraversal(Node localRoot) {
  164. if (localRoot != null) {
  165. postorderTraversal(localRoot.leftChild);
  166. postorderTraversal(localRoot.rightChild);
  167. System.out.print(localRoot.iData + " ");
  168. }
  169. }
  170. }
  171. /**
  172. * 操作数的类
  173. */
  174. public class TreeApp {
  175. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/878941
推荐阅读
相关标签
  

闽ICP备14008679号