搜索

目录

1. 引入

1.1 搜索

1.2 常见容器

1.3 与搜索问题有关的数据结构

2. 搜索树(二叉搜索树)

2.1 定义

2.2 时间复杂度

2.3 查找一个指定数

2.4 插入一个数

2.5 删除一个节点

2.6 缺点

3. 平衡树

3.1 定义

3.2 AVL树

3.3 红黑树

3.3 时间复杂度

4. B-树

4.1 引入

4.2 使用场景

4.3 分类


1. 引入

  • 1.1 搜索

    • —— 听起来是个比较抽象的词语。但其实,在我们的生活中就有很多搜索

      • 生活中的搜索
        • 1. 找出符合条件的集合(eg:找出班级中身高在160cm-180cm之间的同学)
        • 2. 统计符合条件内容出现的次数(eg:一首歌中,出现了多少次“我”)
        • 3. 确定集合中是否包含指定条件的内容(eg:一篇文章中是否包含有“搜索”)
      • 将这些生活中的搜索与数据结构结合起来
        • 前两种搜索可以利用Map<>实现(key-value)
        • 第三种搜索可以利用Set<>实现(key)
  • 1.2 常见容器

    • 分类
      • ArrayList<E>、LinkedList<E>
      • HashMap<K,V>、HashSet<E>
      • TreeMap<K,V>、TreeSet<E>
    • 如何选择
      • 使用键值对选择Map,若只查看是否存在用Set
      • 一般情况下使用Hash,需要天生有序性使用Tree
  • 1.3 与搜索问题有关的数据结构

    • 二分查找
      • 适用
        • 有序数组
        • 已经有序且不会变更的数据
        • 求n的平方根
    • 哈希表
      • 优点
        • 超快 时间复杂度为O(1)
    • 搜索树
      • 优点
        • 天生的有序性,中序遍历是有序的
    • 使用数据库中的查询举例
      • 数据库中的索引
        • 使用B+树,利用搜索树的天生有序性
      • select * from table where id>10;
        • 使用搜索树,查询范围
      • select * from table where id=1;
        • 使用哈希,查询确定值
      • select * from table order by id;
        • 使用搜索树,因为搜索树的天生有序性,无序再次排序

2. 搜索树(二叉搜索树)

  • 2.1 定义

    • 任意节点的左子树的值都小于节点的值,右子树的值都大于节点的值。
    • 搜索树中不存在相同的值
  • 2.2 时间复杂度

    • 当需要查找的数字大于根结点,只需要向右子树攻击;小于根结点,则只需要向左子树攻击。
    • 因此,时间复杂度,即为二叉树的高度 -> O(log(n)) ~O(n)(当该搜索树为一个单支树时,树的高度为O(n))
  • 2.3 查找一个指定数

    • 利用递归实现
      • 终止条件
        • 树为空树  ->  返回false
        • 找到指定值  ->  返回true
      • 递推公式
        • 若所给值小于根结点,在左子树中查找
        • 若大于根结点,在右子树中查找
  • 2.4 插入一个数

    • 利用递归实现
      • 终止条件
        • 树为空树  ->  插入新的节点
        • 若与根结点的值相同,抛出异常
      • 递推公式
        • 若所给值小于根结点,在左子树中插入
        • 若大于根结点,在右子树中插入
      • 注意
        • ∵ 只有当node为空的时候才会插入,∴ 插入会改变当前节点的状态。
          • -> 我们需要将当前节点从null 改为新节点
  • 2.5 删除一个节点

    • 难点
      • 删除后,被删除的节点用谁替代
        • 1. 被删除的节点为叶子节点,直接删除
        • 2. 只有一个孩子的节点,子承父业
        • 3. 两个孩子
          • 替换删除法
            • 找出左孩子中最大的或右孩子中最小的,替换被删除节点
              • 左孩子中的最大的一定没有右孩子;右孩子中最小的一定没有左孩子
    • 递推公式
      • 若所给值小于根结点,在左子树中插入
      • 若大于根结点,在右子树中插入
      • 注意
        • ∵ 只有当node为空的时候才会插入,∴ 插入会改变当前节点的状态。
          • -> 我们需要将当前节点从null 改为新节点
  • 2.6 缺点

    • 高度不确定 -> 时间复杂度不确定

3. 平衡树

  • 3.1 定义

    • 为了解决搜索树高度不确定的情况,平衡树的高度比较接近log(n)
  • 3.2 AVL树

    • 高度平衡二叉树,要求树中每一个左子树的高度和右子树的高度差,不超过1。
      • 难点
        • 随着插入的进行,树可能不平衡
        • 解决方法
          • 旋转
      • 旋转
        • 在每个节点中记录一项属性:平衡因子
          • 平衡因子 = 左子树高度-右子树高度,值为-1、0、1
        • 当插入一个节点时,平衡因子会出现3种情况
          • -1 -> 0
          • 0  -> 1
          • 1  -> 2
          • 只有平衡因子变为2时,才会触发旋转操作
        • 何时旋转
          • 向左子树插入节点,插入后左子树 - 右子树==2
          • 向右子树插入节点,插入后右子树 - 左子树==2
        • 旋转方式
          • 向左子树插入节点
            • node.left.left - node.left.right == 2 ,node右旋
            • node.left.left - node.left.right == -2 ,node.left左旋,node右旋
          • 向右子树插入节点
            • node.right.left - node.risht.right == 2 ,node.right右旋,node左旋
            • node.right.left - node.risht.right == -2 ,node左旋
        • 旋转的是常数时间,不影响插入和删除的时间复杂度,仍为O(log(n))
    • 3.3 红黑树

      • 不是绝对意义上的平衡树,但是接近于平衡树
      • 性质
        • 1. 每个结点有颜色(红或黑  0或1)
        • 2. 红色不能与红色相邻
        • 3. 根结点一定是黑色的
        • 4. 叶子节点(null)是黑色的
        • 5. 从根到每一个叶子,所有这样的路径上,黑色的数量一样多
      • 特点
        • 最长边一定是黑-红-黑-红-黑...
        • 最短边一定是黑-黑-黑...
          • 因此,最长边的长度一定不会超过最短边长度*2
      • 插入
        • 为了不破坏红黑树的性质,插入的点一定是红色的。
        • 存在情况
          • 父亲为黑色,没有破坏红黑树的性质,直接返回
          • 父亲为红色,红红相邻,需调整
            • 特点
              • 这时,父亲定不是根结点(根节点是黑色)
              • 因此,存在祖父节点,且祖父节点定为黑色
            • 如何调整
              • (1)存在红色叔叔节点
                • 把祖父节点变为红色,父亲节点与叔叔节点都变为黑色
              • (2)不存在叔叔节点或存在黑色叔叔节点,且当前节点是父节点的左孩子
                • 右旋后,交换父亲与祖父颜色
              • (3)不存在叔叔节点或存在黑色叔叔节点,且当前节点是父节点的右孩子
                • 从父节点左旋,->(3)
    • 3.2.3 Battle
      • AVL 查找更好一点:高度更加平衡、更低
      • 红黑树 插入/ 删除更好一点:调整次数更少
  • 3.3 时间复杂度

    • 所有平衡搜索树的 插入/删除/查找 的时间复杂度都是O(log(n))

4. B-树

  • 4.1 引入

    • 数据库中使用索引来提高检索效率,那么主要是利用了什么方法呢?
      • 搜索树(B+树(多叉树))
      • 哈希
    • 为什么使用B+树而不使用红黑树呢???
      • 因为B+树是多叉树,在同等数量数据的情况下,高度更低。使得访问磁盘次数更少,效率更高。
  • 4.2 使用场景

    • 多用于磁盘搜索
      • 磁盘:读写效率低
      • B树系列:孩子多,高度低 -> 读写次数少
  • 4.3 分类

    • B-树:值除了在叶子节点,中间节点也保存
    • B+树:值全部在叶子节点中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值