美文网首页
排序算法总结

排序算法总结

作者: 滨岩 | 来源:发表于2020-03-07 10:29 被阅读0次
image.png

归并排序需要临时空间O(n),由于是递归实现,所以应该是O(n+logn),但是logn比n小,所以是O(n)

快速排序由于递归的关系,栈占O(logn)的空间。

堆 最后一个非叶子节点的索引 (count-1)/2

稳定排序

经过排序以后,3的位置排在前面的依然靠前

image.png

稳定排序:对于相等的元素,在排序后,原来靠前的元素依然靠前,相等元素的相对位置没有发生改变。
例如:
1、订单先按照金额排序,然后再按照时间排序,这样在相同的时间下,金额大的或者小的排在前面,如果不是稳定排序,顺序就会错乱。
2、对于学生成绩单排序,刚开始是按照学生姓名顺序排序的,现在再根据学生分数排序,这样相同成绩的学生就按照学生姓名字典排序。

算法至今为止,还没有发现一种算法支持:能够平均时间复杂度O(nlogn)、原地排序、空间复杂度O(1)、而且稳定排序

对一组数据进行排序 场景分析

可能会选择 “快速排序” 复杂度为 O(nlogn)

1、有没有可能包含大量的重复元素?

如果包含大量的重复元素,“三路快排” 是更好的选择,当最后分割的元素小于286个时,分割元素可能更接近于排序,可以用“插入排序”,因为此时用“插入排序”复杂度趋近于O(n)。Java语言中标准库的快速排序就是使用“三路快排”实现的。
可以参考 Collections.sort() 和 Arrays.sort()的源码

下面是 Arrays.sort(); 源码

public static void sort(int[] a) {
    DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}

可以看到这里有一个DualPivotQuicksort,DualPivotQuicksort翻译过来就是双轴快速排序(关于双轴快速排序我们后期在讨论,可以认为是对我们普通使用的快排的一种改进,另外还有一种改进是三路快排!),再次点进去,可以发现有这么一段代码:

if (right - left < QUICKSORT_THRESHOLD) {
    sort(a, left, right, true);
    return;
}

发现如果数组的长度小于QUICKSORT_THRESHOLD的话就会使用这个双轴快速排序,而这个值是286。

那如果大于286呢,它就会判断数组的连续升序和连续降序性好不好,如果好的话就用归并排序,不好的话就用快速排序,看下面这段注释就可以看出:

/*
  * The array is not highly structured,
  * use Quicksort instead of merge sort.
  */   

那现在再回到上面的决定用双轴快速排序的方法上,再点进去,发现又会多一条判断:

// Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD) {
    //。。。。
}

即如果数组长度小于INSERTION_SORT_THRESHOLD(值为47)的话,那么就会用插入排序了,不然再用双轴快速排序!

总结,如果数组长度大于等于286且连续性好的话,就用归并排序,如果大于等于286且连续性不好的话就用双轴快速排序。如果长度小于286且大于等于47的话就用双轴快速排序,如果长度小于47的话就用插入排序。示意图如下:

image.png

是否大部分数据距离它正确位置很近?是否近乎排序?

比如我们现在要对银行业务按照银行业务发生的时间进行排序,大多数银行业务是按照业务完成的时间存入库中,如果按照业务发生的时间来看,是近乎有序的,因为大多数业务先发生也是先完成,只有少数极个别的业务可能处理的时间非常长,如果是这样的话,“插入排序法”可能是更好的选择。

是否数据的取值范围非常有限?

比如:对学生成绩排序,北京高考成绩出来了,高考成绩满分是750分,最低分是0分,它的取值范围为0-750,针对北京高考成绩数据进行排序,在这样的情况下,或许计数排序是更好的选择。

对排序有没有什么特殊的要求,是否需要稳定排序?

如果是的话,归并排序是更好的选择。

如果对数据的存储状态有要求,是否是使用链表存储的?

快排对数据随机存取有要求,如果使用的是链表存储的话,“快速排序”就不适用了,“归并排序”是更好的选择。

数据大小是否可以装载在内存里?

如果数据量很大,或者内存很小,不足以装载在内存里,需要使用外排序算法。

相关文章

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • iOS算法总结-冒泡排序

    iOS算法总结-冒泡排序 iOS算法总结-冒泡排序

  • 算法学习(1)-排序算法

    八大排序算法九大排序算法再总结[经典排序算法][集锦][直观学习排序算法] 视觉直观感受若干常用排序算法 快速排序...

  • 面试常问的排序算法

    排序算法总结 排序是算法问题中的经典问题。为什么要总结排序算法呢?你懂的 : (假设所有的排序都是要求最终结果为:...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 排序算法

    一、排序算法总结 排序算法题目 排序算法快速排序堆排序归并排序 应用最小K个数(TopK问题)215.数组中的第K...

  • 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...

  • Swift的十大经典排序算法总结

    Swift的十大经典排序算法总结 排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排...

  • 算法-排序算法总结

    排序类型总结 1 排序算法基础实现 2 排序算法应用 2.1 基础排序 2.2 计数排序应用 2.3 快排应用 2...

  • 排序算法最强总结及其代码实现(Python/Java)

    前言 本文总结了常用的全部排序算法,内容包括: 排序算法的定义和思路 排序算法的代码实现:Python和Java,...

网友评论

      本文标题:排序算法总结

      本文链接:https://www.haomeiwen.com/subject/ajparhtx.html