数据结构之常用的内部排序

原创 2018年04月15日 11:36:31

写在前面

对于一个排序算法来说,一般从如下三个方面来衡量算法的优劣:

》时间复杂度:主要是分析关键字的比较次数和记录的移动次数

》空间复杂度:分析排序算法需要多少辅助内存

》稳定性:若两个记录A和B的关键字相等,但排序后A,B的先后次序保持不变,则称这种排序算法是稳定的;反之就是不稳定的。


排序分为内部和外部排序的依据是:

如果整个排序过程不需要借助于外部存储器,所有排序操作都放在内存中完成,则为内部排序

常用的内部排序的分类

》选择排序:直接选择排序,堆排序

》交换排序:冒泡排序,快速排序

》插入排序:直接插入排序,折半插入排序,shell排序

》归并排序

》同时排序

》桶式排序

》基数排序


选择排序

只要找到本趟比较中最小的数据,然后拿他和本趟比较中第一位的数据交换。

对于直接选择排序来说,假设有n个数据,数据交换的次数最多有n-1次,但程序的比较次数较多(交换的次数有一些没有必要)。

总体来说,其时间效率为O(n^2)

根据代码结果:直接选择排序是不稳定

 

堆排序

最小堆(树中所有节点都小于其左右子节点的值)和最大堆(树中所有节点都大于其左右子节点的值),分别对应着一棵完全二叉树

对于n个数据元素的数据组而言,堆排序需要经过n-1次建堆,每次建堆的作用就是选出该堆的最大值或最小值。堆排序的本质是一种选择排序

 

堆排序的关键在于建堆

1.从最后一个非叶节点开始,比较该节点和它两个子节点的值;如果某个子结点大于父节点的值,就把父节点和较大的子节点进行交换

2.向前逐步调整直到根节点,即保证每个父节点的值都大于等于其左右子节点的值,建堆完成。

 

对于堆排序来说,假设有n个数据,需要进行n-1次建堆,每次建堆本身耗时log2,n;则其时间效率是O(n*log2,n

堆排序的空间效率很高,它只需要一个附加程序单元用于交换,其空间效率为O(1)

从堆排序的结果来看,它是不稳定的

 

冒泡排序

冒泡排序是最广为人知的交换排序之一,,它具有算法思路简单,容易实现的特点

冒泡排序的每趟交换结束后,不仅能将当前最大值挤出最后面的位置,还能部分理顺前面的其他元素;一旦某一趟没有交换发生,即可提前结束排序。

 

冒泡排序算法的时间效率是不确定的,在最好的情况下,初始序列已经在有序状态,则执行一次冒泡即可,即做n-1次比较,无需交换。

但在最坏的情况下,初始数据序列处于完全逆序状态,算法要执行n-1趟冒泡,第i趟做了n-i个比较,

冒泡排序的空间效率很高,它只需要一个附加程序单元用于交换,O(1)

冒泡排序是稳定的

 

快速排序

是一个速度非常快的交换排序算法

基本思路比较简单:

从待排序的数据序列中人去一个数据(如第一个数据)作为分界值,所有比它小的数据元素一律放在左边,所有比它大的数据元素一律放在右边,经过这样一趟下来,该序列形成两个子序列,接下来对左右两个子序列进行递归,对两个子序列重新选择中心元素并依此调整,直到每一个子序列中的元素只剩一个,排序完成。

快速排序只进过两次交换即可让分界值左边的数据小于分界值,分界值右边的数据大于分界值,因此速度很快。


快速排序的时间效率很好,因为它每趟能确定的元素成指数级增长

快速排序需要使用递归,而递归使用栈,因此它的空间效率为O(log2.n)

另一方面,快速排序这种包含跳跃交换,因此是不稳定的排序算法


插入排序

》直接插入排序

》shell排序

》折半插入排序


直接插入排序

思路很简单:将待排序的数据元素按其关键字的值的大小插入前面的有序序列

直接插入排序的时间效率并不高,在最坏的情况下,所有 元素的比较次数总和为(0+1+2。。。+n-1)=O(n^2)

在其他情况下,也要考虑移动元素的个数,故时间复杂度为O(n^2)

直接插入排序的空间效率很好,他只需要一个缓存数据单元,空间效率为O(1)

稳定的


折半插入排序

折半插入排序是对直接插入排序的简单改进

对于折半插入排序而言,当第i-1趟需要将第i个元素插入前面的0~i-1个元素序列中,他不会直接从第i-1个元素开始比较:

1.计算0~i-1索引的中间点,也就是用i索引处的元素和(0+i-1)/2索引处的元素来进行比较,如果i索引处的元素大,就在另一半的范围内搜索,这就是所谓的折半。

2.不断的折半,将搜索范围缩小到1/2,1/4,1/8.从而快速确定第i个元素的插入位置。

3.确定插入位置后,程序将位置以后的元素整体后移一位,然后将第i个元素放入该位置。

稳定的


shell排序

希尔排序对直接插入排序进行了改进:它通过加大插入排序中元素的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大跨度的移动。

通过创建这些交错的内部有序的数据项集合,就可以减少直接插入排序中数据项”整体搬家“的工作量


希尔排序比插入排序快很多,当间隔即增量h大的时候可以减少很大的移动量,因此效率很高。

shell排序是直接插入排序的改进版,因此也是稳定的,它的空间开销也是O(1)

时间开销大致是O(n的3/2次方)到n的7/6次方)之间


归并排序

”合并排序“:将两个有序的数组进行合并,成为一个新的有序大数组。

归并算法需要递归地进行分解,合并,每进行一趟归并排序需要调用merge(、)方法一次,每次执行merge()算法都要比较n次,因此归并排序算法的时间复杂度是O(n*log2.n)

归并算法的的空间效率比较差,它需要一个与原始序列同样大小的辅助序列

归并排序算法是稳定的


桶式排序

不是一个基于比较的排序方法这种排序方式必须满足两个特征:

》待排序的所有值在一个可枚举范围内

》待排序的可枚举范围不应太大,否则排序开销太大


桶式排序算法是一种极其优秀的算法,时间效率极高,它只需要两轮遍历即可:

第一轮遍历待排数据,统计每个待排数据落入各个桶中的个数;

第二轮遍历用于重新计算每一个桶里的数组元素的值

两轮遍历后就可得到每个待排数据的在有序序列中的位置,然后将每一个数据依次放入指定位置即可

桶式排序的空间开销较大,他需要两个数组

桶式排序数稳定的


常用的排序算法总结(各种内部排序算法和外部排序算法)

  • 2010年08月20日 15:47
  • 866KB
  • 下载

数据结构6种内部排序算法的比较

1、需求分析(1)输入数据的形式为:伪随机数产生程序产生,且每次输入数不少于100个,至少要用5组不同的输入数据(2)输出的形式为:输出关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)...
  • xu_Melon
  • xu_Melon
  • 2017-03-19 10:46:14
  • 1031

数据结构和算法设计专题之---八大内部排序

摘要: 前几天,看到一篇前辈的博文“程序员必知的8大排序”,不禁的手痒起来,重新翻开严蔚敏老师的《数据结构》复习了一遍,然后一一的用java去实现,其中有不足之处,还望各位道友指正出来。...
  • jiangwei0910410003
  • jiangwei0910410003
  • 2014-07-29 11:07:55
  • 3873

数据结构中的各种内部排序的排序过程

总结自《数据结构教程》,书上的太理论化了,本文简单梳理一下给你一组数字怎么去排序。本篇不涉及代码和理论,只说说排序过程。 一、插入排序: 【例子】序列:5,7,9,3,1 第一趟:[5]...
  • weixin_38012570
  • weixin_38012570
  • 2017-11-28 20:32:02
  • 418

内部排序的数据结构实验报告

  • 2009年07月07日 12:49
  • 121KB
  • 下载

【数据结构与算法】内部排序总结(附各种排序算法源码)

这篇博文我们简要地总结下各种内部排序方法。 这10种排序算法中,前面7种属于建立在“比较”基础上的排序算法,通过决策树已经证明,任何基于比较进行的排序算法的时 间复杂度不可能再优于O(n*lo...
  • mmc_maodun
  • mmc_maodun
  • 2014-03-11 00:03:01
  • 5169

数据结构内部排序实验报告

  • 2009年07月08日 18:35
  • 46KB
  • 下载

内部排序与外部排序

排序=内部排序+外部排序 内部排序主要消耗时间复杂度,而外部排序消耗的是空间复杂度;如何权衡时间和空间复杂度? 内部排序一般包括:冒泡,选择,快速排序等; 外部排序则是通过开辟空间,让特定空间有...
  • u014421677
  • u014421677
  • 2016-09-06 15:00:04
  • 607

论数据结构中的内排序和外排序

文章来源:http://d.wanfangdata.com.cn/Periodical_jyj200906030.aspx需要付费;排序是计算机内经常进行的一种操作,分为内部排序和外部排序,内部排序中...
  • buster2014
  • buster2014
  • 2014-12-10 18:36:57
  • 1564
收藏助手
不良信息举报
您举报文章:数据结构之常用的内部排序
举报原因:
原因补充:

(最多只允许输入30个字)