【数据结构】排序算法总结

给出一下排序的实现原理、时间复杂度,空间复杂度,稳定性以及适用场景 
比较排序: 

1. 直接插入排序 

直接插入排序是一种最基本的插入排序方法,其基本思想是将第i个记录直接插入到前面i-1个已排序的序列中。排序的主要算法思想是:每次插入一个元素时先找要插入的位置,将这个位置之后的元素都从后往前都都后移一位,然后在插入位置,插入该元素。

适用场景:在待排序的关键字序列基本有序且关键字个数比较少时,直接插入排序的性能最佳。

时间复杂度:O(n^2) 空间复杂度O(1) 

稳定性:稳定

2. 希尔排序 

希尔排序又称缩小增量排序法,是一种基于插入排序思想的排序算法,它利用了直接插入排序算法的最佳性质,首先将待排序的关键字序列分成若干个较小的子序列,然后对子序列进行直接插入排序,使整个待排序序列排好序。

具体算法实现:先将待排序序列分割成若干个较稀疏的子序列,分别直接进行直接插入排序,,经过上述粗略调整,整个序列中的记录已经基本有序,最后再对全部记录进行一次直接插入排序。

(1)首先选定记录间的距离为d,在整个待排序序列中将所有间隔为d的记录分成一组,进行组内直接插入排序

(2)然后缩小d值,继续将间隔为d的记录分成一组,然后进行组内直接插入排序,

重复第二步多次,直到间隔d变为1,此时只有一个序列,在对该序列进行一次直接插入排序。

说明:增量的选择最初希尔提出,第一次去n/2,以后每次取d/2

时间复杂度:O(n^1.5)  空间复杂度:O(1)

稳定性:不稳定

3. 选择排序(选择排序优化) 

简单选择排序基本思想:在每一趟n-i+1个记录中选取关键字最小的记录作为有序序列中的第i个记录。

具体算法实现:

第一趟选择排序时,从第一个记录开始,通过n-1次关键字的比较,从n个关键字中选取最小的一个关键字,并和第一个记录交换

第二趟选择排序时,从第二个记录开始,通过n-2次关键字的比较,从n-1个关键字中选取最小的一个关键字,并和第二个记录交换

......

重复以上过程,经过n-1趟简单选择排序,就能将所有的记录按照从小到大的顺序进行排序

时间复杂度:O(n^2)  空间复杂度:O(1)

稳定性:不稳定

选择排序优化:(锦标赛排序)

锦标赛排序又称为树形排序。基本思想是先把排序的n个记录的关键字进行两两比较,取出较小者,然后再在n/2个较小者采用同样的方法进行比较,选出每两个中的较小者,如此反复直到找到最小关键字记录为止。

具体算法实现:

基本思想:首先取得n个元素的关键码,进行两两比较,得到n/2(上取整)个比较的优胜者,作为第一步比较的结果保留下来。然后对这n/2(上取整)个元素再进行关键码的两两比较,…,如此重复,直到选出一个关键码最小的元素为止。一旦选择出这个元素,就需要在下次选择最小关键码之前把它的值改为最大值,使它再也不能战胜其他对手,此时需要重构胜者树得到新的优胜者,作为该排序下的下一个元素,重构的时间代价为lg(N)。总共需重构N-1次,锦标赛排序的时间复杂度为N*lgN,空间复杂度O(n),稳定性:稳定

4. 堆排序 

具体算法思想:

(1)创建堆,升序排序需要创建大堆,否则创建小堆,

(2)循环执行如下过程,直到数组为空:

   a、把堆顶array[0]元素和当前最堆的最后一个元素交换

   b、最大堆元素个数减1

   c、由于第1步后根节点不再满足最堆定义,向下调整跟结点。

把一棵完成二叉树调整为堆,以及每次堆顶元素交换后进行调整的时间复杂度均为O(log(n)),所以堆排序的时间复杂度为O(n*log(n))。堆排序是一种不稳定的排序算法。

时间复杂度:O(nlgn)  空间复杂度:O(1)

稳定性:不稳定

5. 冒泡排序(冒泡排序优化) 

基本算法思想:反复扫描待排序记录序列,在扫描的过程中顺次比较相邻的两个元素大小若相邻两个元素逆序,则交换位置,

在扫描过程中,不断将相邻两个关键字大的记录向后移动,最后将待排序序列中的最大关键字换到排序序列的末尾,这也是最大关键字该在的位置。

然后进行第二趟冒泡排序,对前n-1个记录进行相同的操作,

在进行第三趟...

.......

这样一直反复,直到剩下一个最小的记录若在某趟排序过程中没有发现一个逆序,则可直接结束整个排序过程,所以冒泡最多进行n-1趟

时间复杂度:O(n^2)   空间复杂度:O(1)

稳定性:稳定

6. 快排(三种方式以及优化,最优和最差场景以及循环方式的快排) 

基本算方法思想:从待排序序列中选择一个关键字作为枢纽,记为key,将比key小的放在key的左边,比key大的放在key的右边,将待排序序列分成两部分,将关键字为key的记录放在两部分的分界线上,将这个过程称为完成了一趟快速排序,接下来对分割的两部分分别进行快速排序,一直分割,直到枢纽左右的元素个数都不超过1为止,这样待排序序列就变成了一个有序序列,为了让key能尽量靠近中间不会出现取最大值或者最小值这种极端情况,所以第一次快速排序时我们采用三数取中法来确定key值,即在待排序序列选取三个数选取其中中间大小的数作为key值

时间复杂度:O(nlgn)  空间复杂度:O(nlgn)

稳定性:不稳定

外部排序 
7. 归并排序 

归并排序基本思想是基于合并,将两个或两个以上的有序表合并成一个心得有序表,将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后将他们合并成一个序列。合并两个子序列的过程称为两路归并。

具体算法思想:

(1)先将待排序序列不断进行分割,分割成一个个的小区域直到一个小区就含有两个元素,将这个小区域按照顺序排列将排好的小区域再逐渐进行合并,并进行排序,由于之前已经排过序这时的工作就会少很多,直到最后所有小区域都合并为一个完整的序列,最后在整体进行一次排序,就能得到有序序列

时间复杂度:O(nlogn)  空间复杂度:O(n)

稳定性:稳定

非比较排序: 

1. 计数排序 

基本算法思想:假设都是正整数,比如排序数组A,先遍历一遍找到A中最大的数字,重新创建一个数组,数组长度为A中最大数字加一,B数组的作用就是存储A中数组各元素个数,先都初始化为0,遍历A,遇到第一个数A[0]则,B[A[0]]++;遇到第二个元素A[1]则B[A[1]]++;直到将整个A数组遍历完成,

然后将A数组还原,从左到右依次遍历数组B,只要B中元素不为0,假设B中的数字是B[i] = n,则将下标i输出n遍,再判断下一个元素,重复上述操作,直到将B数组遍历完

时间复杂度:O(n)  空间复杂度:O(n)

稳定性:稳定

2. 基数排序(LSD和MSD) 

LSD:

基本算法思想:

就拿两位数来说;

首先根据个位数的数值,在遍历数据时,将所有数据按照个位数字分配到0~9的桶中,即个位数和桶号相同,分配结束后将桶中数据按照从小到大(桶中由底到顶)排序依次重新收集起来,就会得到一个新的无序序列,然后再按照十位数字(十位数字和桶号相对应)分配进去,然后再将所有数字收集起来就能得到一个有序序列

过程如下图:


MSD:与LSD基本相同只是先十位在低位

更多位数的话LSD就是先低位再高位,MSD就是先高位再低位

时间复杂度;O(d(n+rd))  空间复杂度:O(rd)

稳定性:稳定


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值