文章目录

  • 二叉树
    • 特征
  • 二分搜索树 Binary Search Tree
    • 特征
    • 限制(存储的元素必须具有可比性)
  • Code
    • 添加数据
    • 添加数据V2.0
    • 查找 数据

我们简明扼要的整理下二叉树,以及二分搜索树的特征及代码实现


二叉树

我们分析下,二叉树的节点元素 ,除了要存储数据,还有两个引用分别指向其他节点

class Node {E e;Node left ;  // 左孩子 Node right ; // 右孩子
}

特征

  • 和链表一样,是动态数据结构

  • 每个节点最多只能分出来两棵树 (同样类比多叉树)

  • 二叉树具有唯一的根节点


    按照上图, 16就是 28根节点的左孩子, 30 就是28的右孩子 。 依次类推 13是16的左孩子, 22是16的右孩子。 29是30的左孩子, 42是30的右孩子。

  • 二叉树每个节点最多有两个孩子

    叶子节点是没有任何孩子的节点。 上图是一个完整的二叉树 ,实际应用中并不都是这种情况。

  • 二叉树每个节点最多有一个父亲节点,只有根节点没有父亲节点。

  • 二叉树具有天然的递归结构

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

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

  • 二叉树不一定是“满”的


二分搜索树 Binary Search Tree

特征

  • 二分搜索树是二叉树,二叉树的特征全部适用于二分搜索树

  • 二分搜索树的每个节点的值

    大于其左子树的所有节点的值

    小于其右子树的所有节点的值

  • 每一棵子树也是二分搜索树

    比如下面的二分搜索树


限制(存储的元素必须具有可比性)

为什么要这么设计呢?

其实是为了特定的场景,我们使用二分搜索树查询数据的话,这两个数可以比较的话,那么就可以明确的知道这个数据在左边还是在右边了,查询效率高。

所以什么样的数据存到二分搜索树中才能搜索呢? —> 存储的元素必须具有可比较性

整型自然不必说了,可以比较大小,如果我们存储的是个对象,那这个对象一定要能比较 。 举个例子存储的对象为Car , 要么这个Car 可以按照价格比较,要么可以按照重量比较,总之能比较就可以。

在Java中这个对象要继承Comparable接口


Code

添加数据

/*** * * @ClassName: BinarySearchTree* * @Description: 二分搜索树 --> 元素必须可以比较* * @author: Mr.Yang* * @date: 2020年2月8日 下午12:59:02* * @param <E>*/
public class BinarySearchTree<E extends Comparable<E>> {/*** * @ClassName: Node* * @Description: 数据节点类* * @date: 2020年2月8日 下午12:58:44*/private class Node {private E e;// 数据private Node left; // 左孩子private Node right;// 右孩子public Node(E e) {this.e = e;this.left = null;this.right = null;}}private Node root;// 根节点private int size; // 当前数据量/*** * * @Title:BinarySearchTree* * @Description:默认构造函数*/public BinarySearchTree() {this.root = null;this.size = 0;}public int getSize() {return size;}public boolean isEmpty() {return size == 0;}/*** * * @Title: add* * @Description: 向二分搜索树中添加新的元素e* * @param e* * @return: void*/public void add(E e) {// 根节点的非空判断if (root == null) {root = new Node(e);size++;} elseadd(root, e);}/*** * * @Title: add* * @Description: 向以node为根的二分搜索树中插入元素e,递归算法* * @param node* @param e* * @return: void*/private void add(Node node, E e) {if (e.equals(node.e))return;else if (e.compareTo(node.e) < 0 && node.left == null) { // 插入到左子树node.left = new Node(e);size++;return;} else if (e.compareTo(node.e) > 0 && node.right == null) {// 插入到右子树node.right = new Node(e);size++;return;}// 递归调用if (e.compareTo(node.e) < 0)add(node.left, e);else // e.compareTo(node.e) > 0add(node.right, e);}
}

添加数据V2.0

上面的添加方法,OK ,没问题。 但代码量还是有点长

  1. 我们对Root节点做了特殊的非空判断处理,逻辑上不统一
  2. 每次插入都有判断节点必须为null的判断
  3. e.compareTo(node.e)进行了两次的操作才能插入
  4. 终止条件臃肿
  5. 空本身就是一颗二叉树,所以遇到空的情况直接插入即可

e.compareTo(node.e) >(<) 0 && node.right(left) == null 其实并没有递归到底。

/*** * * @Title: add public 属性供外部调用* * @Description: 向二分搜索树中添加新的元素e* * @param e* * @return: void*/public void add(E e) {root = add(root, e);}/*** * * @Title: add 内部调用 私有 递归函数* * @Description: 返回插入新节点后的二分搜索树的根* * @param node* @param e* * @return: void*/private Node add(Node node, E e) {if (node == null) {size++;return new Node(e);}// 相等,不做任何操作if (e.compareTo(node.e) < 0) {node.left = add(node.left, e);} else if (e.compareTo(node.e) > 0) {node.right = add(node.right, e);}return node;}

查找 数据

/*** * * @Title: contains 供外部调用* * @Description: 判断元素e是否存二分搜索树中* * @param e* * @return: boolean*/public boolean contains(E e) {return contains(root, e);}/*** * * @Title: contains 内部调用* * @Description: 判断e是否存在于以node为根的二分搜索树中 递归算法* * @param node* @param e* * @return: boolean*/private boolean contains(Node node, E e) {if (node == null) { // node为空 返回falsereturn false;}if (e.compareTo(node.e) == 0) { // 相等 返回truereturn true;} else if (e.compareTo(node.e) < 0) { // 小, 继续递归左子树return contains(node.left, e);} else { // e.compareTo(node.e) > 0 大, 继续递归右子树return contains(node.right, e);}}

Algorithms_二叉树二分搜索树初探相关推荐

  1. 树、二叉树、二分搜索树

    将数据使用树结构存储后,出去的高效! 二叉树基本概念 二叉树也具有天然的递归结构 二叉树不一定是"满"的.以下均为二叉树 二分搜索树基本概念 二分搜索树代码示例 package B ...

  2. java实现二分搜索树

    1.二分搜索树定义 二分搜索树是一个二叉树 二分搜索树的节点的值大于左子树,小于右子树的值 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAbuFGnW-158419 ...

  3. JS 数据结构之旅 :通过JS实现栈、队列、二叉树、二分搜索树、AVL树、Trie树、并查集树、堆

    JS 数据结构之旅 栈 概念 栈是一个线性结构,在计算机中是一个相当常见的数据结构. 栈的特点是只能在某一端添加或删除数据,遵循先进后出的原则 实现 每种数据结构都可以用很多种方式来实现,其实可以把栈 ...

  4. 二分搜索树--二叉树

    文章目录 前言 一.二叉树 二.二分搜索树的性质 前言 二分搜索树:在二叉树的基础上,任意一个节点满足大于左子树中的所有节点,小于右子树中的所有节点. 一.二叉树 1.为什么要有树结构: 树结构本身是 ...

  5. Algorithms_二叉树的层次遍历(广度优先)

    文章目录 使用树理解深度优先和广度优先 层次遍历分析 Code 使用树理解深度优先和广度优先 我们上篇博文中 Algorithms_二叉树的前序遍历.中序遍历.后续遍历(深度优先) ,本质上是深度优先 ...

  6. Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)

    文章目录 前序.中序.后序的含义 实例 Code (递归) 前序遍历 中序遍历 后序遍历 测试 Code (非递归) 前序.中序.后序的含义 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树 中 ...

  7. 二分查找法及二分搜索树及其C++实现

    二分查找法及二分搜索树及其C++实现 二分查找法 二分查找简介 二分查找的实现 二分搜索树 二分搜索树简介 二分搜索树的实现 二分查找法 二分查找简介 二分查找是一种在每次比较之后将查找空间一分为二的 ...

  8. 算法与数据结构之二分搜索树

    主要介绍:介绍一下二分搜索树相关的知识,有二分查找法.二分搜索树等. 二分查找法 wiki定义 是一种在有序数组中查找某一特定元素的搜索算法.搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元 ...

  9. 数据结构与算法(八)二分搜索树(Binary Search Tree)

    本文主要包括以下内容: 二分搜索树的基本概念 二分搜索树的基本操作 1. 插入 2. 删除 3. 查询 实现二分搜索树 二分搜索树的不足 二分搜索树的基本概念 二分搜索树(英语:Binary Sear ...

最新文章

  1. 使用ThinkPHP实现生成/校验验证码功能
  2. poj 3280(简单区间dp)
  3. LOJ116 有源汇有上下界最大流(上下界网络流)
  4. 闭包 python_根据面试题谈谈 Python 闭包
  5. [C#基础]说说委托+=和-=的那些事
  6. CCIE学习(40)—— OSPF设计与LSA类型(三)
  7. 欧拉函数、欧拉定理、费马小定理(附例题)
  8. mysql是slot_技术分享 | MySQL 主机该如何配置 fs.aio-max-nr
  9. Ubuntu源码安装gcc-10
  10. OBLOG4.0+DVBBS7.10 SP1整合
  11. java使用环信信息推送,环信推送详解
  12. php一年过去多少天,php获取一年有多少天
  13. 《工程伦理与学术道德》第四章习题
  14. 交换机 tagged 与 untagged 的关系
  15. 自学个JAVA编程有什么用_怎样自学java编程
  16. 第一台生物计算机,世界上第一台DNA计算机问世
  17. sql 汉字按照首字母排序
  18. 图文讲解Python数据可视化神器 !
  19. SAP 公司代码与采购组织的分配关系
  20. 跟着乔布斯上一堂管理课

热门文章

  1. tensorflow 风格迁移二
  2. 76. Leetcode 295. 数据流的中位数 (堆-技巧一-固定堆)
  3. 打印N个数组整体最大的TopK
  4. 拼接所有字符串产生字典顺序最小的大写字符串
  5. python笔记: staticmethod classmethod
  6. 文巾解题 595. 大的国家
  7. MATLAB从入门到精通-matlab中符号推导应用及相关技巧
  8. RabbitMQ 还是 Kafka?哪个才是架构利器
  9. 目标检测(Object Detection)原理与实现
  10. A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)