二分搜索树,你还要我怎样?

开发 前端
树是一种很特别的数据结构,树这种数据结构叫做 “树” 就是因为它 长得像一棵树 。但是这棵树画成的图长得却是一棵倒着的树,根在上,叶在下。树是图的一种,树和图的区别就在于:树是没有环的,而图是可以有环的。

 一、树结构

树是一种很特别的数据结构,树这种数据结构叫做 “树” 就是因为它 长得像一棵树 。但是这棵树画成的图长得却是一棵倒着的树,根在上,叶在下。树是图的一种,树和图的区别就在于:树是没有环的,而图是可以有环的。

树状图是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。


二、为什么要有树结构

2.1 树结构是一种天然的组织结构

比如说电脑中的文件夹,我们需要找到一个特定的文件,需要到某个文件夹下去找这个文件,计算机的文件存储的结构来源于生活。再比如说图书馆,我们知道图书馆里面有 历史类、数理类、计算机类,我们想要找到关于java的书籍,就需要到计算机类的Java中去找到我们需要的图书

比如公司里面的层级结构:CEO、HR CTO等等,还有我们比较常见的家谱等等,都是类似于树结构

将数据使用树结构后,会更加的高效

三、二分搜索树

3.1 特点

  • 二分搜索树是一个动态数据结构
  • 二分搜索树也是一颗二叉树(也叫多叉树)
  • 二分搜索树的每个节点的值都大于其左子树的所有节点的值,同时每个节点的值都小于其右子树的所有节点的值
  • 存储的元素必须有可比较性, Java中的话就要求二分搜索树保存的数据类型要实现Comparable接口, 或者使用额外的比较器实现
  • 每一颗子树也是二分搜索树
  • 二分搜索树具有唯一根节点,同时在二叉树中最底下是它的叶子节点

二分搜索树具有唯根节点,每个节点最多有两个孩子(左边的叫左孩子,右边的叫右孩子),同时每个节点最多有一个父亲

二分搜索树天然的具有递归特性

  • 每个节点的左子树也是二叉树
  • 每个节点的右子树也是二叉树

二叉树不一定是满的,一个接电脑也是二叉树、空也是二叉树


四、具体代码实现

在进行相关操作之前, 先定义一个支持泛型的节点类, 用于存储二分搜索树每个节点的信息, 这个类作为二分搜索树的一个内部类, 二分搜索树的类声明以及Node节点类声明如下:

4.1 添加元素

二分搜索树添加元素的非递归写法,和链表很像,由于二分搜索树本身的递归特性, 所以可以很方便的使用递归实现向二分搜索树中添加元素,

代码实现:

  1. //向二分搜索树添加新的元素e 
  2.  
  3. public void add(E e){ 
  4.  
  5. root = add(root,e); 
  6.  
  7.  
  8. //向以Node为根的二分搜索树中插入元素 E,递归算法 
  9.  
  10. //返回插入新节点后二分搜索树的根 
  11.  
  12. private Node add(Node node,E e){ 
  13.  
  14. if(node == null){ 
  15.  
  16. size++; 
  17.  
  18. return new Node(e); 
  19.  
  20.  
  21. if(e.compareTo(node.e) < 0) 
  22.  
  23. node.left = add(node.left,e); 
  24.  
  25. else if(e.compareTo(node.e) > 0) 
  26.  
  27. node.right = add(node.right,e); 
  28.  
  29. return node; 
  30.  

4.2 查找元素

由于二分搜索树没有下标, 所以针对二分搜索树的查找操作, 我们需要定义一个 contains() 方法, 查看二分搜索树是否包含某个元素, 返回一个布尔型变量

代码实现:

  1. //看二分是搜索树中是否包含元素e 
  2.  
  3. public boolean contains(E e){ 
  4.  
  5. return contains(root,e); 
  6.  
  7.  
  8. //看以Node为根的二分搜索树中是否包含元素e,递归算法 
  9.  
  10. private boolean contains(Node node,E e){ 
  11.  
  12. if(node == null
  13.  
  14. return false
  15.  
  16. if(e.compareTo(node.e) == 0) 
  17.  
  18. return true
  19.  
  20. else if(e.compareTo(node.e) < 0) 
  21.  
  22. return contains(node.left,e); 
  23.  
  24. else //e.compareTo(node.e) > 0 
  25.  
  26. return contains(node.right,e); 
  27.  

4.3 遍历操作

一、 什么是遍历操作

  • 遍历操作就是把所有的节点都访问一遍
  • 访问的原因和业务相关
  • 遍历分类

前序遍历 : 对当前节点的遍历在对左右孩子节点的遍历之前, 遍历顺序 : 当前节点->左孩子->右孩子中序遍历 : 对当前节点的遍历在对左右孩子节点的遍历中间, 遍历顺序 : 左孩子->当前节点->右孩子后序遍历 : 对当前节点的遍历在对左右孩子节点的遍历之后, 遍历顺序 : 左孩子->右孩子->当前节点二、 前序遍历

  1. //二分搜索树前序遍历 
  2.  
  3. public void preOrder(){ 
  4.  
  5. preOrder(root); 
  6.  
  7.  
  8. //前序遍历以Node为根的二分搜索树,递归算法 
  9.  
  10. private void preOrder(Node node){ 
  11.  
  12. if(node == null
  13.  
  14. return
  15.  
  16. System.out.println(node.e); 
  17.  
  18. preOrder(node.left); 
  19.  
  20. preOrder(node.right); 
  21.  
  22.  
  23. public void preOrderNR(){ 
  24.  
  25. Stack stack = new Stack<>(); 
  26.  
  27. stack.push(root); 
  28.  
  29. while(!stack.isEmpty()){ 
  30.  
  31. Node cur = stack.pop(); 
  32.  
  33. System.out.println(cur.e); 
  34.  
  35. if(cur.right != null
  36.  
  37. stack.push(cur.right); 
  38.  
  39. if(cur.left != null
  40.  
  41. stack.push(cur.left); 
  42.  
  43.  

三、 中序遍历


  1. //二分搜索树的中序遍历 
  2.  
  3. public void inOrder(){ 
  4.  
  5. inOrder(root); 
  6.  
  7.  
  8. //中序遍历以Node为根的二分搜索树,递归算法 
  9.  
  10. private void inOrder(Node node){ 
  11.  
  12. if(node ==null
  13.  
  14. return
  15.  
  16. inOrder(node.left); 
  17.  
  18. System.out.println(node.e); 
  19.  
  20. inOrder(node.right); 
  21.  

四、 后序遍历


  1. //二分搜索树的后序遍历 
  2.  
  3. public void postOrder(){ 
  4.  
  5. inOrder(root); 
  6.  
  7.  
  8. public void levelOrder(){ 
  9.  
  10. Queue q = new LinkedList(); 
  11.  
  12. q.add(root); 
  13.  
  14. while (!q.isEmpty()){ 
  15.  
  16. Node cur = q.remove(); 
  17.  
  18. System.out.println(cur.e); 
  19.  
  20. if(cur.left != null
  21.  
  22. q.add(cur.left); 
  23.  
  24. if(cur.right != null
  25.  
  26. q.add(cur.right); 
  27.  
  28.  
  29.  
  30. //后序遍历以Node为根的二分搜索树,递归算法 
  31.  
  32. private void postOrder(Node node){ 
  33.  
  34. if(node ==null
  35.  
  36. return
  37.  
  38. inOrder(node.left); 
  39.  
  40. inOrder(node.right); 
  41.  
  42. System.out.println(node.e); 
  43.  

五、 理解前中后


二分搜索树前序非递归写法

 


 

责任编辑:姜华 来源: 牧小码农
相关推荐

2021-05-21 08:31:09

数据结构二叉树

2022-06-26 00:29:26

分布式系统Redis

2023-10-10 14:03:47

swap排序解法

2024-08-19 08:02:58

2021-09-06 10:38:50

二叉搜索树递归

2023-09-16 18:35:53

二分查找算法

2022-03-29 07:52:21

运用技巧二分查找

2021-11-01 12:55:43

网络

2022-03-28 10:03:58

二分查找算法

2020-12-08 06:32:04

Kafka二分查找

2022-12-26 00:51:33

双向链表二叉搜索树

2019-07-04 15:57:16

内存频率DDR4

2023-12-22 09:37:13

二分查找数组数据库

2022-03-18 08:37:12

二分查找算法元素

2023-12-27 23:30:50

2021-08-31 11:35:24

二叉搜索树迭代法公共祖先

2021-12-07 06:55:17

二叉搜索树链表

2021-10-14 07:55:20

二分查找面试

2023-08-29 08:31:13

B+树数据索引

2022-12-05 09:42:14

C++Python算法
点赞
收藏

51CTO技术栈公众号