概要

在前面分别介绍了"二叉查找树的相关理论知识,然后给出了二叉查找树的C和C++实现版本"。这一章写一写二叉查找树的Java实现版本。

目录

1. 二叉树查找树
2. 二叉查找树的Java实现
3. 二叉查找树的Java测试程序

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3576452.html


更多内容数据结构与算法系列 目录

(01) 二叉查找树(一)之 图文解析 和 C语言的实现
(02) 二叉查找树(二)之 C++的实现
(03) 二叉查找树(三)之 Java的实现

二叉查找树简介

二叉查找树(Binary Search Tree),又被称为二叉搜索树。
它是特殊的二叉树:对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。那么,这棵树就是二叉查找树。如下图所示:

在二叉查找树中:
(01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(03) 任意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。

二叉查找树的Java实现

1. 二叉查找树节点的定义

  1. public class BSTree<T extends Comparable<T>> {
  2.  
  3. private BSTNode<T> mRoot; // 根结点
  4.  
  5. public class BSTNode<T extends Comparable<T>> {
  6. T key; // 关键字(键值)
  7. BSTNode<T> left; // 左孩子
  8. BSTNode<T> right; // 右孩子
  9. BSTNode<T> parent; // 父结点
  10.  
  11. public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right) {
  12. this.key = key;
  13. this.parent = parent;
  14. this.left = left;
  15. this.right = right;
  16. }
  17. }
  18.  
  19. ......
  20. }

BSTree是二叉树,它保护了二叉树的根节点mRoot;mRoot是BSTNode类型,而BSTNode是二叉查找树的节点,它是BSTree的内部类。BSTNode包含二叉查找树的几个基本信息:
(01) key -- 它是关键字,是用来对二叉查找树的节点进行排序的。
(02) left -- 它指向当前节点的左孩子。
(03) right -- 它指向当前节点的右孩子。
(04) parent -- 它指向当前节点的父结点。

2 遍历

这里讲解前序遍历、中序遍历、后序遍历3种方式。

2.1 前序遍历
若二叉树非空,则执行以下操作:
(01) 访问根结点;
(02) 先序遍历左子树;
(03) 先序遍历右子树。

前序遍历代码

  1. private void preOrder(BSTNode<T> tree) {
  2. if(tree != null) {
  3. System.out.print(tree.key+" ");
  4. preOrder(tree.left);
  5. preOrder(tree.right);
  6. }
  7. }
  8.  
  9. public void preOrder() {
  10. preOrder(mRoot);
  11. }

2.2 中序遍历

若二叉树非空,则执行以下操作:
(01) 中序遍历左子树;
(02) 访问根结点;
(03) 中序遍历右子树。

中序遍历代码

  1. private void inOrder(BSTNode<T> tree) {
  2. if(tree != null) {
  3. inOrder(tree.left);
  4. System.out.print(tree.key+" ");
  5. inOrder(tree.right);
  6. }
  7. }
  8.  
  9. public void inOrder() {
  10. inOrder(mRoot);
  11. }

2.3 后序遍历

若二叉树非空,则执行以下操作:
(01) 后序遍历左子树;
(02) 后序遍历右子树;
(03) 访问根结点。

后序遍历代码

  1. private void postOrder(BSTNode<T> tree) {
  2. if(tree != null)
  3. {
  4. postOrder(tree.left);
  5. postOrder(tree.right);
  6. System.out.print(tree.key+" ");
  7. }
  8. }
  9.  
  10. public void postOrder() {
  11. postOrder(mRoot);
  12. }

看看下面这颗树的各种遍历方式:

对于上面的二叉树而言,
(01) 前序遍历结果: 3 1 2 5 4 6
(02) 中序遍历结果: 1 2 3 4 5 6 
(03) 后序遍历结果: 2 1 4 6 5 3

3. 查找

递归版本的代码

  1. /*
  2. * (递归实现)查找"二叉树x"中键值为key的节点
  3. */
  4. private BSTNode<T> search(BSTNode<T> x, T key) {
  5. if (x==null)
  6. return x;
  7.  
  8. int cmp = key.compareTo(x.key);
  9. if (cmp < 0)
  10. return search(x.left, key);
  11. else if (cmp > 0)
  12. return search(x.right, key);
  13. else
  14. return x;
  15. }
  16.  
  17. public BSTNode<T> search(T key) {
  18. return search(mRoot, key);
  19. }

非递归版本的代码

  1. /*
  2. * (非递归实现)查找"二叉树x"中键值为key的节点
  3. */
  4. private BSTNode<T> iterativeSearch(BSTNode<T> x, T key) {
  5. while (x!=null) {
  6. int cmp = key.compareTo(x.key);
  7.  
  8. if (cmp < 0)
  9. x = x.left;
  10. else if (cmp > 0)
  11. x = x.right;
  12. else
  13. return x;
  14. }
  15.  
  16. return x;
  17. }
  18.  
  19. public BSTNode<T> iterativeSearch(T key) {
  20. return iterativeSearch(mRoot, key);
  21. }

4. 最大值和最小值

查找最大值的代码

  1. /*
  2. * 查找最大结点:返回tree为根结点的二叉树的最大结点。
  3. */
  4. private BSTNode<T> maximum(BSTNode<T> tree) {
  5. if (tree == null)
  6. return null;
  7.  
  8. while(tree.right != null)
  9. tree = tree.right;
  10. return tree;
  11. }
  12.  
  13. public T maximum() {
  14. BSTNode<T> p = maximum(mRoot);
  15. if (p != null)
  16. return p.key;
  17.  
  18. return null;
  19. }

查找最小值的代码

  1. /*
  2. * 查找最小结点:返回tree为根结点的二叉树的最小结点。
  3. */
  4. private BSTNode<T> minimum(BSTNode<T> tree) {
  5. if (tree == null)
  6. return null;
  7.  
  8. while(tree.left != null)
  9. tree = tree.left;
  10. return tree;
  11. }
  12.  
  13. public T minimum() {
  14. BSTNode<T> p = minimum(mRoot);
  15. if (p != null)
  16. return p.key;
  17.  
  18. return null;
  19. }

5. 前驱和后继

节点的前驱:是该节点的左子树中的最大节点。
节点的后继:是该节点的右子树中的最小节点。

查找前驱节点的代码

  1. /*
  2. * 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
  3. */
  4. public BSTNode<T> predecessor(BSTNode<T> x) {
  5. // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
  6. if (x.left != null)
  7. return maximum(x.left);
  8.  
  9. // 如果x没有左孩子。则x有以下两种可能:
  10. // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
  11. // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
  12. BSTNode<T> y = x.parent;
  13. while ((y!=null) && (x==y.left)) {
  14. x = y;
  15. y = y.parent;
  16. }
  17.  
  18. return y;
  19. }

查找后继节点的代码

  1. /*
  2. * 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
  3. */
  4. public BSTNode<T> successor(BSTNode<T> x) {
  5. // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
  6. if (x.right != null)
  7. return minimum(x.right);
  8.  
  9. // 如果x没有右孩子。则x有以下两种可能:
  10. // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
  11. // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
  12. BSTNode<T> y = x.parent;
  13. while ((y!=null) && (x==y.right)) {
  14. x = y;
  15. y = y.parent;
  16. }
  17.  
  18. return y;
  19. }

6. 插入

插入节点的代码

  1. /*
  2. * 将结点插入到二叉树中
  3. *
  4. * 参数说明:
  5. * tree 二叉树的
  6. * z 插入的结点
  7. */
  8. private void insert(BSTree<T> bst, BSTNode<T> z) {
  9. int cmp;
  10. BSTNode<T> y = null;
  11. BSTNode<T> x = bst.mRoot;
  12.  
  13. // 查找z的插入位置
  14. while (x != null) {
  15. y = x;
  16. cmp = z.key.compareTo(x.key);
  17. if (cmp < 0)
  18. x = x.left;
  19. else
  20. x = x.right;
  21. }
  22.  
  23. z.parent = y;
  24. if (y==null)
  25. bst.mRoot = z;
  26. else {
  27. cmp = z.key.compareTo(y.key);
  28. if (cmp < 0)
  29. y.left = z;
  30. else
  31. y.right = z;
  32. }
  33. }
  34.  
  35. /*
  36. * 新建结点(key),并将其插入到二叉树中
  37. *
  38. * 参数说明:
  39. * tree 二叉树的根结点
  40. * key 插入结点的键值
  41. */
  42. public void insert(T key) {
  43. BSTNode<T> z=new BSTNode<T>(key,null,null,null);
  44.  
  45. // 如果新建结点失败,则返回。
  46. if (z != null)
  47. insert(this, z);
  48. }

注:本文实现的二叉查找树是允许插入相同键值的节点的。若想禁止二叉查找树中插入相同键值的节点,可以参考"二叉查找树(一)之 图文解析 和 C语言的实现"中的插入函数进行修改。

7. 删除

删除节点的代码

  1. /*
  2. * 删除结点(z),并返回被删除的结点
  3. *
  4. * 参数说明:
  5. * bst 二叉树
  6. * z 删除的结点
  7. */
  8. private BSTNode<T> remove(BSTree<T> bst, BSTNode<T> z) {
  9. BSTNode<T> x=null;
  10. BSTNode<T> y=null;
  11.  
  12. if ((z.left == null) || (z.right == null) )
  13. y = z;
  14. else
  15. y = successor(z);
  16.  
  17. if (y.left != null)
  18. x = y.left;
  19. else
  20. x = y.right;
  21.  
  22. if (x != null)
  23. x.parent = y.parent;
  24.  
  25. if (y.parent == null)
  26. bst.mRoot = x;
  27. else if (y == y.parent.left)
  28. y.parent.left = x;
  29. else
  30. y.parent.right = x;
  31.  
  32. if (y != z)
  33. z.key = y.key;
  34.  
  35. return y;
  36. }
  37.  
  38. /*
  39. * 删除结点(z),并返回被删除的结点
  40. *
  41. * 参数说明:
  42. * tree 二叉树的根结点
  43. * z 删除的结点
  44. */
  45. public void remove(T key) {
  46. BSTNode<T> z, node;
  47.  
  48. if ((z = search(mRoot, key)) != null)
  49. if ( (node = remove(this, z)) != null)
  50. node = null;
  51. }


8. 打印

打印二叉查找树的代码

  1. /*
  2. * 打印"二叉查找树"
  3. *
  4. * key -- 节点的键值
  5. * direction -- 0,表示该节点是根节点;
  6. * -1,表示该节点是它的父结点的左孩子;
  7. * 1,表示该节点是它的父结点的右孩子。
  8. */
  9. private void print(BSTNode<T> tree, T key, int direction) {
  10.  
  11. if(tree != null) {
  12.  
  13. if(direction==0) // tree是根节点
  14. System.out.printf("%2d is root\n", tree.key);
  15. else // tree是分支节点
  16. System.out.printf("%2d is %2d's %6s child\n", tree.key, key, direction==1?"right" : "left");
  17.  
  18. print(tree.left, tree.key, -1);
  19. print(tree.right,tree.key, 1);
  20. }
  21. }
  22.  
  23. public void print() {
  24. if (mRoot != null)
  25. print(mRoot, mRoot.key, 0);
  26. }

9. 销毁

销毁二叉查找树的代码

  1. /*
  2. * 销毁二叉树
  3. */
  4. private void destroy(BSTNode<T> tree) {
  5. if (tree==null)
  6. return ;
  7.  
  8. if (tree.left != null)
  9. destroy(tree.left);
  10. if (tree.right != null)
  11. destroy(tree.right);
  12.  
  13. tree=null;
  14. }
  15.  
  16. public void clear() {
  17. destroy(mRoot);
  18. mRoot = null;
  19. }

完整的实现代码
二叉查找树的Java实现文件(BSTree.java)

  1. /**
  2. * Java 语言: 二叉查找树
  3. *
  4. * @author skywang
  5. * @date 2013/11/07
  6. */
  7.  
  8. public class BSTree<T extends Comparable<T>> {
  9.  
  10. private BSTNode<T> mRoot; // 根结点
  11.  
  12. public class BSTNode<T extends Comparable<T>> {
  13. T key; // 关键字(键值)
  14. BSTNode<T> left; // 左孩子
  15. BSTNode<T> right; // 右孩子
  16. BSTNode<T> parent; // 父结点
  17.  
  18. public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right) {
  19. this.key = key;
  20. this.parent = parent;
  21. this.left = left;
  22. this.right = right;
  23. }
  24.  
  25. public T getKey() {
  26. return key;
  27. }
  28.  
  29. public String toString() {
  30. return "key:"+key;
  31. }
  32. }
  33.  
  34. public BSTree() {
  35. mRoot=null;
  36. }
  37.  
  38. /*
  39. * 前序遍历"二叉树"
  40. */
  41. private void preOrder(BSTNode<T> tree) {
  42. if(tree != null) {
  43. System.out.print(tree.key+" ");
  44. preOrder(tree.left);
  45. preOrder(tree.right);
  46. }
  47. }
  48.  
  49. public void preOrder() {
  50. preOrder(mRoot);
  51. }
  52.  
  53. /*
  54. * 中序遍历"二叉树"
  55. */
  56. private void inOrder(BSTNode<T> tree) {
  57. if(tree != null) {
  58. inOrder(tree.left);
  59. System.out.print(tree.key+" ");
  60. inOrder(tree.right);
  61. }
  62. }
  63.  
  64. public void inOrder() {
  65. inOrder(mRoot);
  66. }
  67.  
  68. /*
  69. * 后序遍历"二叉树"
  70. */
  71. private void postOrder(BSTNode<T> tree) {
  72. if(tree != null)
  73. {
  74. postOrder(tree.left);
  75. postOrder(tree.right);
  76. System.out.print(tree.key+" ");
  77. }
  78. }
  79.  
  80. public void postOrder() {
  81. postOrder(mRoot);
  82. }
  83.  
  84. /*
  85. * (递归实现)查找"二叉树x"中键值为key的节点
  86. */
  87. private BSTNode<T> search(BSTNode<T> x, T key) {
  88. if (x==null)
  89. return x;
  90.  
  91. int cmp = key.compareTo(x.key);
  92. if (cmp < 0)
  93. return search(x.left, key);
  94. else if (cmp > 0)
  95. return search(x.right, key);
  96. else
  97. return x;
  98. }
  99.  
  100. public BSTNode<T> search(T key) {
  101. return search(mRoot, key);
  102. }
  103.  
  104. /*
  105. * (非递归实现)查找"二叉树x"中键值为key的节点
  106. */
  107. private BSTNode<T> iterativeSearch(BSTNode<T> x, T key) {
  108. while (x!=null) {
  109. int cmp = key.compareTo(x.key);
  110.  
  111. if (cmp < 0)
  112. x = x.left;
  113. else if (cmp > 0)
  114. x = x.right;
  115. else
  116. return x;
  117. }
  118.  
  119. return x;
  120. }
  121.  
  122. public BSTNode<T> iterativeSearch(T key) {
  123. return iterativeSearch(mRoot, key);
  124. }
  125.  
  126. /*
  127. * 查找最小结点:返回tree为根结点的二叉树的最小结点。
  128. */
  129. private BSTNode<T> minimum(BSTNode<T> tree) {
  130. if (tree == null)
  131. return null;
  132.  
  133. while(tree.left != null)
  134. tree = tree.left;
  135. return tree;
  136. }
  137.  
  138. public T minimum() {
  139. BSTNode<T> p = minimum(mRoot);
  140. if (p != null)
  141. return p.key;
  142.  
  143. return null;
  144. }
  145.  
  146. /*
  147. * 查找最大结点:返回tree为根结点的二叉树的最大结点。
  148. */
  149. private BSTNode<T> maximum(BSTNode<T> tree) {
  150. if (tree == null)
  151. return null;
  152.  
  153. while(tree.right != null)
  154. tree = tree.right;
  155. return tree;
  156. }
  157.  
  158. public T maximum() {
  159. BSTNode<T> p = maximum(mRoot);
  160. if (p != null)
  161. return p.key;
  162.  
  163. return null;
  164. }
  165.  
  166. /*
  167. * 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
  168. */
  169. public BSTNode<T> successor(BSTNode<T> x) {
  170. // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
  171. if (x.right != null)
  172. return minimum(x.right);
  173.  
  174. // 如果x没有右孩子。则x有以下两种可能:
  175. // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
  176. // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
  177. BSTNode<T> y = x.parent;
  178. while ((y!=null) && (x==y.right)) {
  179. x = y;
  180. y = y.parent;
  181. }
  182.  
  183. return y;
  184. }
  185.  
  186. /*
  187. * 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。
  188. */
  189. public BSTNode<T> predecessor(BSTNode<T> x) {
  190. // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
  191. if (x.left != null)
  192. return maximum(x.left);
  193.  
  194. // 如果x没有左孩子。则x有以下两种可能:
  195. // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
  196. // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
  197. BSTNode<T> y = x.parent;
  198. while ((y!=null) && (x==y.left)) {
  199. x = y;
  200. y = y.parent;
  201. }
  202.  
  203. return y;
  204. }
  205.  
  206. /*
  207. * 将结点插入到二叉树中
  208. *
  209. * 参数说明:
  210. * tree 二叉树的
  211. * z 插入的结点
  212. */
  213. private void insert(BSTree<T> bst, BSTNode<T> z) {
  214. int cmp;
  215. BSTNode<T> y = null;
  216. BSTNode<T> x = bst.mRoot;
  217.  
  218. // 查找z的插入位置
  219. while (x != null) {
  220. y = x;
  221. cmp = z.key.compareTo(x.key);
  222. if (cmp < 0)
  223. x = x.left;
  224. else
  225. x = x.right;
  226. }
  227.  
  228. z.parent = y;
  229. if (y==null)
  230. bst.mRoot = z;
  231. else {
  232. cmp = z.key.compareTo(y.key);
  233. if (cmp < 0)
  234. y.left = z;
  235. else
  236. y.right = z;
  237. }
  238. }
  239.  
  240. /*
  241. * 新建结点(key),并将其插入到二叉树中
  242. *
  243. * 参数说明:
  244. * tree 二叉树的根结点
  245. * key 插入结点的键值
  246. */
  247. public void insert(T key) {
  248. BSTNode<T> z=new BSTNode<T>(key,null,null,null);
  249.  
  250. // 如果新建结点失败,则返回。
  251. if (z != null)
  252. insert(this, z);
  253. }
  254.  
  255. /*
  256. * 删除结点(z),并返回被删除的结点
  257. *
  258. * 参数说明:
  259. * bst 二叉树
  260. * z 删除的结点
  261. */
  262. private BSTNode<T> remove(BSTree<T> bst, BSTNode<T> z) {
  263. BSTNode<T> x=null;
  264. BSTNode<T> y=null;
  265.  
  266. if ((z.left == null) || (z.right == null) )
  267. y = z;
  268. else
  269. y = successor(z);
  270.  
  271. if (y.left != null)
  272. x = y.left;
  273. else
  274. x = y.right;
  275.  
  276. if (x != null)
  277. x.parent = y.parent;
  278.  
  279. if (y.parent == null)
  280. bst.mRoot = x;
  281. else if (y == y.parent.left)
  282. y.parent.left = x;
  283. else
  284. y.parent.right = x;
  285.  
  286. if (y != z)
  287. z.key = y.key;
  288.  
  289. return y;
  290. }
  291.  
  292. /*
  293. * 删除结点(z),并返回被删除的结点
  294. *
  295. * 参数说明:
  296. * tree 二叉树的根结点
  297. * z 删除的结点
  298. */
  299. public void remove(T key) {
  300. BSTNode<T> z, node;
  301.  
  302. if ((z = search(mRoot, key)) != null)
  303. if ( (node = remove(this, z)) != null)
  304. node = null;
  305. }
  306.  
  307. /*
  308. * 销毁二叉树
  309. */
  310. private void destroy(BSTNode<T> tree) {
  311. if (tree==null)
  312. return ;
  313.  
  314. if (tree.left != null)
  315. destroy(tree.left);
  316. if (tree.right != null)
  317. destroy(tree.right);
  318.  
  319. tree=null;
  320. }
  321.  
  322. public void clear() {
  323. destroy(mRoot);
  324. mRoot = null;
  325. }
  326.  
  327. /*
  328. * 打印"二叉查找树"
  329. *
  330. * key -- 节点的键值
  331. * direction -- 0,表示该节点是根节点;
  332. * -1,表示该节点是它的父结点的左孩子;
  333. * 1,表示该节点是它的父结点的右孩子。
  334. */
  335. private void print(BSTNode<T> tree, T key, int direction) {
  336.  
  337. if(tree != null) {
  338.  
  339. if(direction==0) // tree是根节点
  340. System.out.printf("%2d is root\n", tree.key);
  341. else // tree是分支节点
  342. System.out.printf("%2d is %2d's %6s child\n", tree.key, key, direction==1?"right" : "left");
  343.  
  344. print(tree.left, tree.key, -1);
  345. print(tree.right,tree.key, 1);
  346. }
  347. }
  348.  
  349. public void print() {
  350. if (mRoot != null)
  351. print(mRoot, mRoot.key, 0);
  352. }
  353. }

二叉查找树的C++测试程序(BSTreeTest.java)

  1. /**
  2. * Java 语言: 二叉查找树
  3. *
  4. * @author skywang
  5. * @date 2013/11/07
  6. */
  7. public class BSTreeTest {
  8.  
  9. private static final int arr[] = {1,5,4,3,2,6};
  10.  
  11. public static void main(String[] args) {
  12. int i, ilen;
  13. BSTree<Integer> tree=new BSTree<Integer>();
  14.  
  15. System.out.print("== 依次添加: ");
  16. ilen = arr.length;
  17. for(i=0; i<ilen; i++) {
  18. System.out.print(arr[i]+" ");
  19. tree.insert(arr[i]);
  20. }
  21.  
  22. System.out.print("\n== 前序遍历: ");
  23. tree.preOrder();
  24.  
  25. System.out.print("\n== 中序遍历: ");
  26. tree.inOrder();
  27.  
  28. System.out.print("\n== 后序遍历: ");
  29. tree.postOrder();
  30. System.out.println();
  31.  
  32. System.out.println("== 最小值: "+ tree.minimum());
  33. System.out.println("== 最大值: "+ tree.maximum());
  34. System.out.println("== 树的详细信息: ");
  35. tree.print();
  36.  
  37. System.out.print("\n== 删除根节点: "+ arr[3]);
  38. tree.remove(arr[3]);
  39.  
  40. System.out.print("\n== 中序遍历: ");
  41. tree.inOrder();
  42. System.out.println();
  43.  
  44. // 销毁二叉树
  45. tree.clear();
  46. }
  47. }

在二叉查找树的Java实现中,使用了泛型,也就意味着支持任意类型; 但是该类型必须要实现Comparable接口。

二叉查找树的Java测试程序

上面的BSTreeTest.java是二叉查找树树的测试程序,运行结果如下:

  1. == 依次添加: 1 5 4 3 2 6
  2. == 前序遍历: 1 5 4 3 2 6
  3. == 中序遍历: 1 2 3 4 5 6
  4. == 后序遍历: 2 3 4 6 5 1
  5. == 最小值: 1
  6. == 最大值: 6
  7. == 树的详细信息:
  8. 1 is root
  9. 5 is 1's right child
  10. 4 is 5's left child
  11. 3 is 4's left child
  12. 2 is 3's left child
  13. 6 is 5's right child
  14.  
  15. == 删除根节点: 3
  16. == 中序遍历: 1 2 4 5 6

下面对测试程序的流程进行分析!

(01) 新建"二叉查找树"root。

(02) 向二叉查找树中依次插入1,5,4,3,2,6 。如下图所示:

(03) 遍历和查找
插入1,5,4,3,2,6之后,得到的二叉查找树如下:

前序遍历结果: 1 5 4 3 2 6 
中序遍历结果: 1 2 3 4 5 6 
后序遍历结果: 2 3 4 6 5 1 
最小值是1,而最大值是6。

(04) 删除节点4。如下图所示:

(05) 重新遍历该二叉查找树。
中序遍历结果: 1 2 4 5 6

二叉查找树(三)之 Java的实现的更多相关文章

  1. AVL树(三)之 Java的实现

    概要 前面分别介绍了AVL树"C语言版本"和"C++版本",本章介绍AVL树的Java实现版本,它的算法与C语言和C++版本一样.内容包括:1. AVL树的介绍 ...

  2. 伸展树(三)之 Java的实现

    概要 前面分别通过C和C++实现了伸展树,本章给出伸展树的Java版本.基本算法和原理都与前两章一样.1. 伸展树的介绍2. 伸展树的Java实现(完整源码)3. 伸展树的Java测试程序 转载请注明 ...

  3. 二叉堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的Java实现(完整源码) ...

  4. 左倾堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了左倾堆,本章给出左倾堆的Java版本.还是那句老话,三种实现的原理一样,择其一了解即可. 目录1. 左倾堆的介绍2. 左倾堆的图文解析3. 左倾堆的Java实现(完整 ...

  5. 斐波那契堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了斐波那契堆,本章给出斐波那契堆的Java版本.还是那句老话,三种实现的原理一样,择其一了解即可. 目录1. 斐波那契堆的介绍2. 斐波那契堆的基本操作3. 斐波那契堆 ...

  6. (第三章)Java内存模型(下)

    一.happens-before happens-before是JMM最核心的概念.对于Java程序员来说,理解happens-before是理解JMM的关键. 1.1 JMM的设计 从JMM设计者的 ...

  7. 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  8. 三种java 去掉字符串中的重复字符函数

    三种java 去掉字符串中的重复字符函数 public static void main(string[] args) { system.out.println(removerepeatedchar( ...

  9. 实验三《Java面向对象程序设计》实验报告

    20162308 实验三<Java面向对象程序设计>实验报告 实验内容 XP基础 XP核心实践 IDEA工具学习 密码学算法基础 实验步骤 (一)Refactor/Reformat使用 p ...

随机推荐

  1. CStringArray用法

    CStringArray使用之前先设置数组尺寸SetSize,才能使用SetAt                  CStringArray m_strScrkRfid ;               ...

  2. 安装Python图型处理库Python Imaging Library(PIL)

    方法1: 在Debian/Ubuntu Linux下直接通过apt安装: $sudo apt-get install python-imaging Mac和其他版本的Linux可以直接使用easy_i ...

  3. Android 使WebView支持HTML5 Video(全屏)播放的方法

    http://blog.csdn.net/zrzlj/article/details/8050633  1)需要在AndroidManifest.xml文件中声明需要使用HardwareAcceler ...

  4. Revit中如何控制图元的显示与隐藏

    Revit建模过程中经常会遇到图元的相互遮挡的情况,为了将一些图元显示出来,就需要将一些不需要显示的图元隐藏掉,这就需要用到"隐藏/重置"工具,在Revit绘图窗口左下角提供了一排 ...

  5. Zookeeper开源客户端框架Curator简介[转]

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

  6. 趣拍SDK接入问题Android

    Android接入趣拍问题. 大部分android开发者第一次下载SDK后,特别是导入到eclipse后,可以运行工程,但点击app中的record没反映,每次点击record按钮 会出现如下log. ...

  7. 进程间通信(IPC)介绍

    进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量.共享存储.Socket ...

  8. WCF 数据服务 4.5

    .NET Framework 4.5 其他版本 WCF 数据服务(以前称为"ADO.NET Data Services")是 .NET Framework 的一个组件.可以使用此组 ...

  9. 定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表

    最近项目中有一种需求: 大致需求是这样的 通过给定的 用户名和密码 要定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表 项目的结构式struts1 hibernat ...

  10. BTrace入门教程

    bin版:https://kenai.com/projects/btrace/downloads/directory/releases 源码:https://github.com/btraceio/b ...