概述
文章目录
- 一、时间复杂度与空间复杂度
- 1.【10种常见的排序算法】带*星号的重要
- 2.【排序算法分类】
- 3.【如何理解排序不稳定?】
- 【代码】[从代码理解算法的不稳定性](https://blog.csdn.net/User_bie/article/details/123580018)
- 4.【如何写算法程序?】
- 5.【如何验证写的算法是否正确?】对数器概念
- 【代码】[对数器验证算法正确性](https://blog.csdn.net/User_bie/article/details/123580176)
- 二、排序算法(讨论升序)
- 1.选择排序:不稳定
- 【代码】[选择排序代码](https://blog.csdn.net/User_bie/article/details/123579610)
- 2.冒泡排序:稳定
- 【代码】[冒泡排序代码](https://blog.csdn.net/User_bie/article/details/123580559)
- 3.*插入排序:稳定 -- 推荐使用
- 【代码】 [插入排序代码](https://blog.csdn.net/User_bie/article/details/123584269)
- 【3种简单排序】
- 4.*堆排序
- 5.希尔排序 - 不稳
- 【如何设置最高效的间隔序列】
- 【代码】
- 6.*归并排序 - 稳定 java对象排序推荐使用 - 稳定
- 【TimSort 多路归并排序】直接将组数分为多块,再两两归并成一个新数组,再递归合并。
- 【代码】[归并排序代码](https://blog.csdn.net/User_bie/article/details/123586090)
- 7.*快速排序(单轴) - 不稳定
- 【代码】 [快速排序代码](https://blog.csdn.net/User_bie/article/details/123586299)
- 【双轴快排】
- 8.桶排序
- 9.计数排序 - 稳定(高考名词排名等)
- 【代码】 [计数排序代码](https://blog.csdn.net/User_bie/article/details/123586414)
- 10.基数排序 - 稳定
- 【代码】 [基数排序代码](https://blog.csdn.net/User_bie/article/details/123586577)
整理自:马士兵数据结构与算法
一、时间复杂度与空间复杂度
【理解】
时间复杂度:代码语句执行的总次数
空间复杂度:指的是是否需要申请额外的空间来存储
1.【10种常见的排序算法】带*星号的重要
最好能背下来
主要三要素:平均复杂度、空间复杂度、稳定性
重要4种:插入排序、堆排序、归并排序、快速排序
2.【排序算法分类】
3.【如何理解排序不稳定?】
稳定性指的是对于关键字相等的两个记录,他们在序列中的相对位置在排序前后不发生改变。
如:A和B有相等关键字,A的位置为 i ,B的位置是 j ,此时 i >j,排序后他们位置依然是A在B前面
排序稳定性有哪些好处?
第一个排序结果可以为另一个排序结果所使用。如关键字相同的记录其他数据不一致,这时交换他们就会引起问题。
如,银行有1个VIP用户和普通用户,他们存款相同,如果交换了他们的角色,让普通用户有了VIP权限,就会引发问题。
【代码】从代码理解算法的不稳定性
4.【如何写算法程序?】
1.由简单到复杂
- 验证一步走一步
- 多打印中间结果
2.先局部后整体
- 没思路时先分析
3.先粗糙后精细
- 变量更名
- 语句合并
- 边界处理 最后处理
5.【如何验证写的算法是否正确?】对数器概念
1.肉眼观察
2.产生足够多随机样本
3.用确定正确的算法计算随机样本
4.对比被验证算法的结果:自己写的算法与正确的算法(Arrays.sort())结果对比
【代码】对数器验证算法正确性
二、排序算法(讨论升序)
1.选择排序:不稳定
【思想】找到数组中最小值,与数组最前一值做交换;再取剩下的值同理操作
时间复杂度:n^2
空间复杂度:1
【扩展】找到数组中最大和最小值,最小值与最前值做交换,最大与最后值做交换。
时间复杂度: n*logn
空间复杂度:1
【图解算法思想】
【代码】选择排序代码
2.冒泡排序:稳定
【思想】相邻两个数两两比较,谁小排前面
时间复杂度:n^2
空间复杂度:1
【如图】
【代码】冒泡排序代码
3.*插入排序:稳定 – 推荐使用
对于基本有序的数组最好用
【思想】通过临时变量,当前临时变量位置与前一个数进行比较,如果前一个数大于临时变量,那么直接将前一个位置向后移位1次,并且记录移动的次数作为最终临时变量值的下标。
【图解插入排序第二种实现方式流程】
【代码】 插入排序代码
【3种简单排序】
总结3种简单排序的基本算法:
冒泡:基本不用,太慢
选择:基本不用,不稳
插入:样本小,基本有序的时候效率比较高
4.*堆排序
5.希尔排序 - 不稳
【思想】:指定数组的最初间隔,取出所有在间隔点上的数,进行一次循环排序
当所有间隔排序完后,数组最终是大致有序的。最终还是要以间隔为1排序一次
【优点】间隔比较大时,交换移动时次数比较小,间隔变小时,交换移动的距离比较小
【如何指定间隔?】
高级的插入排序:
数组以最初间隔为4来操作,最终必须要以间隔为1来排序:
间隔为1排序就是普通的插入排序了
【间隔为4】
【间隔为2】
【间隔为1】
【如何设置最高效的间隔序列】
最小序列:h=gap=1
最序列公式:h=gap=3h+1
例子:最小序列h=1,那么第一个间隔h=3h+1=4,第二个间隔为h=34+1=13,第三个间隔为h=133+1=40
【代码】
希尔排序代码
6.*归并排序 - 稳定 java对象排序推荐使用 - 稳定
归并排序和快排需要使用递归
【算法思想】开辟一个新数组,将一个数组进行多次对半分,每次都有leftBound(左边界),right(下标位置),rightBound(右边界),直到不可再分为止(递归终止条件),然后对每小段数组进行合并并把值写到新数组。递归再将数组二分进行排序。
与快排相比,归并排序是通过下标进行操作;
【大致模型】
【TimSort 多路归并排序】直接将组数分为多块,再两两归并成一个新数组,再递归合并。
【代码】归并排序代码
7.*快速排序(单轴) - 不稳定
【思想】数组中随机取一个元素与最后一个元素进行交换,并设置为初始轴。
定义左右边界,同时向中间移动,直到左边的值小于左边轴值,并且右边的值大于轴值,此时将两个数进行交换,再将轴值与最左边的值位置进行交换,并返回轴下标。
以新轴下标为分界点,分别向左向右进行递归。
与归并相比,快排排序是通过轴(值的大小)进行操作;
【思想】
【代码】 快速排序代码
【双轴快排】
【思想】在单轴快排的思想上,对数组取双轴,将数组分为3个区域,分别对这三个区域进行递归
【多轴快排】:对数组取多个轴,将数组划分为n个区域,对每块区域进行递归排序
8.桶排序
【思想】求出最大值与最小值,然后分成几个桶,对每个桶进行快排或归并排序
此算法不常用:
桶排序最常用的是两种特殊例子:【计数排序】与【基数排序】
9.计数排序 - 稳定(高考名词排名等)
桶排序的一种特殊情况
【思想】指定计数长度数组大小(与原数组的值的范围相关),遍历原数组,取原数组的值对应计数数组的下标相比,每出现1次,在计数数组下标位置的值加1,。定义新的数组,将计数数组下标与对应出现的次数依次写入到新数组中
【代码】 计数排序代码
10.基数排序 - 稳定
桶排序的一种特殊情况
【思想】计算数组最大数求出最大位数(决定外层循环次数),计算个位数并对个位数的放在一个桶,对其进行排序,累加位置(记录了相同数的最大位置),再对十位、百位…进行排序,对累加数组进行拆解(累减),存放在新数组中
【代码】 基数排序代码
最后
以上就是奋斗宝贝为你收集整理的10种常见排序算法-理解附代码一、时间复杂度与空间复杂度二、排序算法(讨论升序)的全部内容,希望文章能够帮你解决10种常见排序算法-理解附代码一、时间复杂度与空间复杂度二、排序算法(讨论升序)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复