计算机的核心作用就是计算、存储,其中数据结构与算法直接决定了计算机的计算效率。所以学好数据结构与算法是做好计算机软件工作非常基础的能力。日常工作中遇到最多的莫过于排序、搜索,本文将针对这两类算法做个探索。

1 时间复杂度

在介绍具体的算法之前,先看下不同的时间复杂度的区别如下图所示。

2 排序算法

排序算法常见的主要有交换排序、插入排序、选择排序、计数排序等

一般算法都是优先考虑时间复杂度,故下面先根据时间复杂度进行分类分析

2.1 对于冒泡排序、直接选择排序、简单插入排序,都是需要两两比较的,唯一的不同就是比较完之后处理方式的不同,以及比较顺序的不同,故时间复杂度都为O(n^2)。

(1)冒泡排序:从第1个数开始,两两比较后大数往右移,完了再从第1个数开始新的一轮比较,直到整个序列是有序的。

(2)直接选择排序:从现有无序序列中选出最小的1个数放在序列的首位,然后再从剩余的数中继续选出最小的,直到整个序列有序。选择的时候做两两比较。

(3)简单插入排序:从现有无序的序列中选择一个数,插入到有序序列的合适位置,插入的时候才做两两比较。

2.2 对于快速排序,核心是通过二分法,随机取一个数,比他小的放在左边,比他大的放在右边,递归完成。这样做的好处就是无需每次都两两比较,比较范围会越来越小。时间复杂度为O(n * logn)

2.3 如果可以不受空间的约束,可以考虑通过空间换时间,获得时间复杂度更好的排序算法,就是计数算法。计数算法就是把待排序的数当作数组的索引,放入对应的数组中,按索引从小到大取数即可。

日常较通用的就是交换排序与快速排序算法了。

3 搜索算法

参考

https://www.jianshu.com/p/908f0366e1dc

https://www.jianshu.com/p/95d224c4d13e

https://blog.csdn.net/hao65103940/article/details/89032538

https://blog.csdn.net/yang_yulei/article/details/26066409

搜索、排序不分家,一般搜索都会涉及排序,当然也有无序搜索。总体而言有这么几种常用的搜索算法:顺序搜索、插值搜索、树表搜索等。各种搜索算法的时间复杂度如下所示。

3.1 树表查找

首先从最复杂的树表查找开始讲,说到树查找,不得不先说说广度优先搜索、深度优先搜素。其实这两种搜索算法只是一种图的遍历方式,工程上不见得就是最优的算法,除了要遍历所有的节点还要额外的空间。

广度优先搜索:类似于层序遍历,可以借助队列实现。大致的算法实现步骤如下

1)选择一个顶点作为起始顶点,放入队列中

2)从队列首部取出一个顶点,标记为已读,同时将该顶点的所有相连依次放入队列尾部

3)重复步骤2

深度优先搜索:深度优先搜索更像是一条路走到黑,走不去回到上个路口选择另外一条路继续走,可以借助堆栈实现。

选定一个顶点作为起始顶点,能前进则前进,若不能前进则后退一步继续前进,或者再后退一步选择另一条路前进,依次类推,直到所有顶点都被遍历

对于一颗树而言,最常见的就是二叉树,当然也有多叉树,比如B-tree、B+tree等,总体而言,常见的有二叉树、平衡二叉树、2-3树、红黑树、B-tree、B+tree等,下面一一介绍。

3.1.1 二叉树

左子树的节点值要小于根节点,右子树的节点值要大于根节点。当二叉树的左右两颗子树分布不均匀的时候,要查找某个叶子节点时,需要遍历比较多的节点。只有当左右两颗子树分布均匀的时候,遍历层数才最小,也就是当二叉树平衡的时候。

最差的情况下查找时间复杂度为O(n),最好的时候也是平衡的时候为O(logN)

3.1.2 平衡二叉树

根节点两边子树的最大高度差为1。对于数这种数据结构,树的最大高度就是最大查找次数,所以尽量要减少树的高度,让树保持平衡。

3.1.3 2-3树(2叉-3叉树)

2叉表示1个键值2条链接到子树,3叉表示2个键值3条链接到子树。2-3树是为了高效自平衡的。一颗完美平衡的2-3树,所有空链接(叶子节点)到根节点的距离都是相同的。

2-3树插入节点的方式:先找插入节点的位置,若节点有空(即2叉节点),则直接插入;若节点没有空(即3叉节点),则先插入使其暂时容纳这个元素,然后分裂此节点,把中间元素移到其父节点中,对父节点亦如此处理。(中键一直往上移,直到找到空位,在此过程中若没有空位就先搞个临时的,再分裂)

2-3树在最坏情况下,仍有较好的性能,每个操作中处理每个节点的时间都不会超过一个很小的常数,且这个操作都只会访问同一条路径上的节点。所以任何查找或者插入操作时间成本都不会超过对数级别。

3.1.4 红黑树

平衡二叉树,当插入或者减少节点时容易打破平衡,红黑树就是一种自平衡的二叉树。是对2-3树的标准化,具备标准的2叉树特性,同时又能够自平衡。

红黑树就是用红色链接表示3叉节点的2-3树,所以红黑树的自平衡就转化为了2-3树的自平衡,红黑树插入节点就转为了2-3树插入节点。我们将3叉节点表示为由一条左斜的红色链接相连的两个2叉节点,就是红黑树,所有的红色链接必须左斜。

红黑树的另一种定义是满足下列条件的二叉查找树:

1)红链接均为左链接

2)没有任何一个节点同时和两条红链接相连

3)该树是完美黑色平衡的,即任意空链接到根节点的路径上的黑链接数量相同

3.1.5 B-tree

b-tree是一种平衡多路查找树,为了优化外存储(磁盘等)的查找效率而产生的一种数据结构。磁盘IO的单位是磁盘块,所以要尽量减少IO次数,每个磁盘块中尽量存储多的键值对以及该索引键两边的磁盘块地址,即B-tree是一颗多叉树,尽量减少树的总层高,减少IO次数,提高查询效率。

3.1.6 B+tree

b+tree作为b-tree的一种优化结构,b-tree的每个树节点会存储键-值,b+tree只会存储键,只有叶子节点才会存储键-值,这样b+tree的每个节点就可以存储更多的索引键,进一步降低了树的高度,查询效率会更高。

InnoDB用的就树B+tree索引(分为聚集索引:叶子节点包括了键与整行的数据;辅助索引:叶子节点只有键没有整行数据,需要根据索引键进一步查询聚集索引才能查出整行数据),层高在2~4层,根节点常驻内存,所以一般磁盘IO数为1~3。同时B+tree的叶子节点组成了有序列表,便于区间查找。b+tree与b-tree都属于多叉树。

Innodb存储结构,一个表只有一个聚集索引(主键索引),其他索引都是二级索引,都是非聚集索引。

3.2 插值查找

最经典的就是二分查找,前提是对于有序表。比较适用于静态表,对于动态表的效果不好,因为要不停地排序,时间复杂度会提高。对于动态表的查找可以用平衡二叉树的方式查找,比如红黑树等。

除了二分查找,还有升级版的斐波拉契查找等,就是事先定义一个初始化的查找点,而不是笼统地从(二分)中间位置查找。

插值查找时间复杂度一般为O(logN)

3.3 顺序查找

顺序查找就是字面意思,逐个查找,时间复杂度为O(N)

3.4 哈希查找

如果不在乎空间,可以空间换时间,使用计数查找,之间使用键值作为数值的索引,时间复杂度为O(1)。如果不在乎时间,可以使用顺序查找。而哈希查找正是一个折中,使用适度的空间与时间在这两者之间达到了平衡。通过哈希函数,可以灵活调整查找时间复杂度。当函数非常离散时就相当于是计数查找,当不离散时,就是个链表,相当于顺序查找。

更多算法请听下回分解。


更多精彩内容,欢迎关注

知乎:https://www.zhihu.com/people/mei-an-63

微信:

算法揭秘之——排序与搜索相关推荐

  1. python希尔排序的优缺点_Python排序搜索基本算法之希尔排序实例分析

    本文实例讲述了Python排序搜索基本算法之希尔排序.分享给大家供大家参考,具体如下: 希尔排序是插入排序的扩展,通过允许非相邻的元素进行交换来提高执行效率.希尔排序最关键的是选择步长,本程序选用Kn ...

  2. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  3. python数据结构和算法 时间复杂度分析 乱序单词检测 线性数据结构 栈stack 字符匹配 表达式求值 queue队列 链表 递归 动态规划 排序和搜索 树 图

    python数据结构和算法 参考 本文github 计算机科学是解决问题的研究.计算机科学使用抽象作为表示过程和数据的工具.抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性.Pytho ...

  4. KDD'21 | 揭秘Facebook升级版语义搜索技术

    上一篇分享了KDD'21 | 淘宝搜索中语义向量检索技术Que2Search: Fast and Accurate Query and Document Understanding for Searc ...

  5. Numpy入门教程:06. 排序,搜索和计数

    背景 什么是 NumPy 呢? NumPy 这个词来源于两个单词 – Numerical和Python.其是一个功能强大的 Python 库,可以帮助程序员轻松地进行数值计算,通常应用于以下场景: 执 ...

  6. 自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索、推荐以及算法相关工作。多年来主要从事推荐系统以及机

    自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索.推荐以及算法相关工作.多年来主要从事推荐系统以及机 ...

  7. 归并排序执行次数_肯定能懂的常见算法讲解(1)——排序算法

    我叫水水,很高兴认识大家! 这是专栏的第七篇文章.其实本专题已经在我的公众号(公众号中不只有学习专题,还有很多大学学习资源分享.工具分享等等,文末有相关指路哦,欢迎关注撒~[微信搜索"Cod ...

  8. 今日头条核心技术“个性推荐算法”揭秘

    今日头条核心技术"个性推荐算法"揭秘 最近面试华兴资本, 他们比较关注今日头条算法的实现, 今天特转载网上 今日头条算法解密 [IT168 评论]互联网给用户带来了大量的信息,满足 ...

  9. 【数据结构、算法】八大排序算法概述(算法复杂度、稳定性)

    前言   排序是计算机程序设计中一个非常重要的操作,它将一个数据元素(或记录)的任意序列重新排列成一个按关键字有序的序列.在有序的序列中查找元素的效率很高,(例如,折半查找法的平均查找长度为log2( ...

最新文章

  1. 全球经济美国中国日本英国欧元区德国法国意大利西班牙
  2. 印象笔记三级目录_我的印象笔记使用手册
  3. idea 新建一个spring项目
  4. android编程中setLayoutParams方法设置
  5. python鸭制作类代码_详细解释ducktyping鸭子类型程序设计与Python的实现
  6. hexo+github 一小时搭建个人博客
  7. AIoT、DevOPS、数据平台、开源,你不可不知的微软 Azure 黑科技大公开
  8. android studio for android learning (二十八) android基础知识
  9. Java实现PDF添加图片水印和文字水印
  10. input取消焦点 vue_vue获取input焦点,弹框后自动获取input焦点
  11. Python中统一快速更换变量的名称
  12. Flink CheckPoint : Exceeded checkpoint tolerable failure threshold
  13. Canonical Coin Systems
  14. linux 机器无法访问网络
  15. 一个40岁的男人如果穷得一无所有该怎么办?
  16. 当前电子计算机发展的局限性,当前高中信息技术教学现状及教学改革探究
  17. 判断字符串数组能否首尾相连
  18. ecshop mysql 报错_修复ecshop数据库ecs_sessions.MYI报错
  19. 前端如何保存图片?并在相册中查看。
  20. php如何设置随机数字和字母,PHP获取随机数字和字母的方法大全

热门文章

  1. 字节跳动有状态应用云原生实践
  2. idea使用git拉取代码到本地库
  3. UML建模-面向对象设计
  4. idea设置中文字体不倾斜
  5. python—matplotlib 散点图,气泡图,气泡饼图/功效矩阵可视化对比
  6. 2016年5月14日 厦门 KTV点歌系统数据库修复误格式化 数据库碎片重组找回
  7. python中mean的用法_Python Pandas Series.mean()用法及代码示例
  8. 重游非故地——WD泰国硬盘工厂概览
  9. 【mysql】关于checkpoint机制
  10. 高质量的超高分辨率图像分割(论文简读)