数据结构与算法(1)----->排序
这一版块,把必备的数据结构和算法做一个总结!包括排序、队列、链表、二叉树、排组合,动态规划......。
总结的过程包括理论部分,练题目可以自己去leetcode/牛客网刷起来~
第一篇文章讲排序~
1. 经典的排序算法
分为时间复杂度为 O(n的平方)的: 冒泡排序、选择排序、插入排序;
时间复杂度为 O( n 乘 log N)的: 归并排序、快速排序、堆排序、希尔排序
时间复杂度为 O(n)的排序算法:计数排序算法、基数排序算法;
1.1 冒泡排序
冒泡排序的时间复杂度为 O(n的平方)。
例如一个数组: 7 3 5 6 0 4 1 2
冒泡排序思路:(对比下图来看)
- 第一次交换区间是0~N-1,第一和第二个数字进行比较,大的数字放在后面;接着第二第三个数字进行比较,同样,大的放在后面。如此,依次进行交换,直到换到最后一个数N-1。这样,最大的数字就到了N-1位置;
- 第二次交换的区间变为0~N-2(最后一个数字不需要再移动了),比较方法类似步骤一;最后,第二大的数字到达了N-2的位置;
- 依次交换,直到最后一次交换区间变为0,整个数组此时已经变得有序,结束。
图画得有点丑,将就着看吧~
1.2 选择排序
选择排序的时间复杂度为 O(n的平方)。
例如一个数组: 7 3 5 6 0 4 1 2
选择排序思路:
- 第一次在区间0~N-1中,选出数组的最小值放到位置0上;
- 第二次在在区间1~N-1中,选出最小值放到位置1上;
- 依次选择,直到最后选择到最后的数值,放到N-1位置上;结束。
这个图画得好看点儿了吧~
1.3 插入排序
插入排序的时间复杂度为 O(n的平方)。
例如一个数组: 7 3 5 6 0 4 1 2
插入排序思路:
- 第一次,对第0和第1位置上的数字进行比较小放左边(前),大的方右边(后);
- 第二次,对第1位置和第2位置进行比较,选出较小值放到位置1上,较大值也就到了第2位置;这个时候需要对第1位置和第2位置再次进行比较,最小的放到最前;
- 依次比较下去,直到最后比较到最后的第N-1位置的数值和第N-2位置大的数值比较,较小的依次与前面的各个位置比较置换,比较到第0和第1位置之后结束。
画图好麻烦啊!!
1.4 归并排序
归并排序的时间复杂度为 O( n 乘 log N)。
例如一个数组: 7 3 5 6 8 4 1 2
归并排序思路:
- 第一次,把划分成为N个小区间;相邻两两区间进行合并,得到N/2个有序区间
- 第二次,把相邻的区间再次合并,得到N/4个有序区间;
- 依次类推,直到把最后两个有序区间合并成一个区间,结束;
如图:
1.5 快速排序(划重点!!!很重要)
快速排序的时间复杂度为 O( n 乘 log N)。
例如一个数组: 7 3 5 6 0 4 1 2
快速排序思路:
- 随机选择数组中的一个元素,把小于等于该数的元素统一放在数组的左边,大于该数的元素放在数组的右边;
- 分别对左右两个部分,再次采用快排思路,随机在期间找一个元素,同样,大于的右侧,小于等于的放在左侧;
- 依次递归下去,完成排序。
画图好麻烦啊!!
1.6 堆排序
堆排序的时间复杂度为 O( n 乘 log N)。
例如一个数组: 7 3 5 6 0 4 1 2
堆排序思路:
- 将堆写成由大到小的堆分支;堆顶为最大值
- 将堆顶元素提出,堆顶元素放到右侧,脱离堆;
- 将新的堆(N-1个元素)进行调整,重复步骤1、2,直到完成最后一个元素,结束。
画图好麻烦啊!!
1.7 希尔排序
希尔排序的时间复杂度为 O( n 乘 log N)。希尔排序是插入排序的一种改良做法。
插入排序前面已经介绍过了,可以知道,插入排序是1位一位往前比较的(步长为1)。而希尔排序初始步长为 >1,遍历结束之后步长减少1,直到最后步长为1时遍历完成,这样结束。
例如一个数组: 7 3 5 6 0 4 1 2
希尔排序思路:
- 假设初始步长为3(自己设置的),从第四位元素和第一位元素进行比较,大小为逆序则交换两者位置,大小为顺序则保留原位置;
- 接着比较第5位和第2位(5往前跑步长3啊),同理,大小为逆序则交换两者位置,大小为顺序则保留原位置;
- 依次类推,完成这一轮次的比较;
- 接着降低步长变为2,同样的方法
- 最后步长为1,遍历完成后结束排序。
下面这个图做的是步长为3的,降低步长方法一致,这里不画了~
1.8 计数排序(源于桶排序思想)
时间复杂度为O(N)。举个例子说明他的思想。
例如:对 张三(168) 李四(178) 王五(188) 的身高排序;
其思路是,建立N个桶,比如100,101,102,...,199(共100个桶),接着将张三,李四,王五放入自己对应的桶中。最后,依次将100~199桶中的数倒出来,也就得到了他们的身高顺序了。
看图:
1.9 基数排序 (源于桶排序思想)
数组元素本身,先按照个位进行排序,放入0~9号桶中;再按照十位排序,放到桶中,依次上升百位...
例如: 对 011 014 023 072 084 101 进行排序
2. 经典排序算法空间复杂度、稳定性
空间复杂度:
空间复杂度 | 算法 |
O(1) | 插入排序、选择排序、冒泡排序、堆排序、希尔排序 |
O(log N) | 快速排序 |
O(N) | 归并排序 |
O(M) | 计数排序、基数排序 |
稳定性:(是否破坏相邻性,破坏则不稳定)
稳定的排序算法 | 插入排序、冒泡排序、归并排序、计数排序、基数排序、桶排序 |
不稳定的排序算法 | 希尔排序、选择排序、快速排序、堆排序 |
数据结构与算法(1)----->排序的更多相关文章
- javascript数据结构与算法--高级排序算法
javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
- javascript数据结构与算法--基本排序算法(冒泡、选择、排序)及效率比较
javascript数据结构与算法--基本排序算法(冒泡.选择.排序)及效率比较 一.数组测试平台. javascript数据结构与算法--基本排序(封装基本数组的操作),封装常规数组操作的函数,比如 ...
- python 数据结构与算法之排序(冒泡,选择,插入)
目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习 ...
- Java数据结构和算法 - 高级排序
希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...
- Java数据结构和算法 - 简单排序
Q: 冒泡排序? A: 1) 比较相邻的元素.如果第一个比第二个大,就交换它们两个; 2) 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数; 3) 针 ...
- 数据结构与算法——常用排序算法及其Java实现
冒泡排序 原理:依次比较相邻的两个数,将小数放在前面(左边),大数放在后面(右边),就像冒泡一样具体操作:第一趟,首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前 ...
- 数据结构与算法系列——排序(4)_Shell希尔排序
1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...
- javascript数据结构与算法--基本排序算法分析
javascript中的基本排序算法 对计算机中存储的数据执行的两种最常见操作是排序和检索,排序和检索算法对于前端开发尤其重要,对此我会对这两种算法做深入的研究,而不会和书上一样只是会贴代码而已,下面 ...
随机推荐
- which 命令详解
一.which 作用: which 命令用于查找并显示给定命令的绝对路径,环境变量PATH中保存了查找命令时需要遍历的目录, which 命令会在环境变量$PATH 设置的目录里查找符合条件的文件.也 ...
- Hello 2018, Bye 2017
2017年过去了,过去一年经历了太多,改变了好多好多,可以说人生进入了另一个阶段,有可能是成熟吧. 回顾2017 去年换了新工作,离开了将近工作了8年的公司,不带走一丝云彩,为其任劳任怨,最后没有任何 ...
- qt中线程的使用方法
QT中使用线程可以提高工作效率. 要使用线程要经过一下四个步骤: (1)先创建一个c++ class文件,记得继承Thread,创建步骤如下: a.第一步 b.第二步 (2)自定义一个run函数,以后 ...
- K:java中枚举的常见用法
用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. ...
- 《吸血鬼日记》(The Vampire Diaries)经典台词
Best quotes from The Vampire Diary 1. I will start fresh, be someone new. 1.我要重新开始,做不一样的自己. 2. It’s ...
- SQLSERVER 死锁标志
最开始做DBA的时候,整天死锁到头痛1222,至今都能回想到这个错误窗口: 死锁定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待 ...
- 如何在开发时部署和运行前后端分离的JavaWeb项目
在开发中大型的JavaEE项目时,前后端分离的框架逐渐成为业界的主流,传统的单机部署前后端在同一个项目中的工程项目越来越少.这类JavaWeb项目的后端通常都采用微服务的架构,后端会被分解为诸多个小项 ...
- chrome调试工具高级不完整使用指南(优化篇)
上一篇文章我们说了chrome调试工具的一些比较基础功能的用法,接下来我们要在这一篇文章中说一说,其他一些chrome调试工具的使用方法 2.1.5 Network模块 在netWork模块中,大致上 ...
- Android CoordinatorLayout、AppBarLayout、DrawerLayout、NavigationView 的使用及问题小结
这里只对Material Design中这几种组件使用的重要部分以及容易出现问题的地方进行汇总(遇坑请直接看最后常见问题部分),详细用法请自行查阅官方文档 一.CoordinatorLayout 介绍 ...
- 记录一次APP的转让流程
由于业务需要,需要将开发的App从一个账号(A账号)转移到另一个账号(B账号),这里简单介绍一下转让流程.主要包括两大步骤: 转让方(A账号)提出转让申请 接收方(B账号)接受转让App 如果不想看这 ...