10种常见排序算法-理解附代码

文章目录

整理自:马士兵数据结构与算法

一、时间复杂度与空间复杂度

【理解】
时间复杂度:代码语句执行的总次数
空间复杂度:指的是是否需要申请额外的空间来存储

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=3
h+1=4,第二个间隔为h=34+1=13,第三个间隔为h=133+1=40

【代码】

希尔排序代码

6.*归并排序 - 稳定 java对象排序推荐使用 - 稳定

归并排序和快排需要使用递归

【算法思想】开辟一个新数组,将一个数组进行多次对半分,每次都有leftBound(左边界),right(下标位置),rightBound(右边界),直到不可再分为止(递归终止条件),然后对每小段数组进行合并并把值写到新数组。递归再将数组二分进行排序。
与快排相比,归并排序是通过下标进行操作;

【大致模型】
在这里插入图片描述

【TimSort 多路归并排序】直接将组数分为多块,再两两归并成一个新数组,再递归合并。

【代码】归并排序代码

7.*快速排序(单轴) - 不稳定

【思想】数组中随机取一个元素与最后一个元素进行交换,并设置为初始轴。
定义左右边界,同时向中间移动,直到左边的值小于左边轴值,并且右边的值大于轴值,此时将两个数进行交换,再将轴值与最左边的值位置进行交换,并返回轴下标。
以新轴下标为分界点,分别向左向右进行递归。
与归并相比,快排排序是通过轴(值的大小)进行操作;

【思想】
在这里插入图片描述

【代码】 快速排序代码

【双轴快排】

【思想】在单轴快排的思想上,对数组取双轴,将数组分为3个区域,分别对这三个区域进行递归
【多轴快排】:对数组取多个轴,将数组划分为n个区域,对每块区域进行递归排序
在这里插入图片描述

8.桶排序

【思想】求出最大值与最小值,然后分成几个桶,对每个桶进行快排或归并排序
此算法不常用:
桶排序最常用的是两种特殊例子:【计数排序】与【基数排序】

9.计数排序 - 稳定(高考名词排名等)

桶排序的一种特殊情况
【思想】指定计数长度数组大小(与原数组的值的范围相关),遍历原数组,取原数组的值对应计数数组的下标相比,每出现1次,在计数数组下标位置的值加1,。定义新的数组,将计数数组下标与对应出现的次数依次写入到新数组中

在这里插入图片描述

【代码】 计数排序代码

10.基数排序 - 稳定

桶排序的一种特殊情况
【思想】计算数组最大数求出最大位数(决定外层循环次数),计算个位数并对个位数的放在一个桶,对其进行排序,累加位置(记录了相同数的最大位置),再对十位、百位…进行排序,对累加数组进行拆解(累减),存放在新数组中
在这里插入图片描述

【代码】 基数排序代码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值