C语言----排序算法

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。


快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;


时间开销

排序的时间开销可用算法执行中的数据比较次数与数据移动次数来衡量。

算法运行时间代价的大略估算一般都按平均情况进行估算。对于那些受对象排序码序列初始排列及对象个数影响较大的,需要按最好情况和最坏情况进行估算

空间开销

算法执行时所需的附加存储。


1.插入排序—直接插入排序(Straight Insertion Sort)


基本思想:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。


直接插入排序示例:

像扑克摸牌一样,插入即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中……第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。 

以下面5个无序的数据为例: 

65 27 59 64 58 (文中仅细化了第四次插入过程) 

第1次插入: 27 65 59 64 58 

第2次插入: 27 59 65 64 58 

第3次插入: 27 59 64 65 58 

第4次插入: 27 58 59 64 65

算法的实现:


2. 插入排序—折半插入排序(二分插入)


算法简介

二分(折半)插入(Binary insert sort)排序是一种在直接插入排序算法上进行小改动的排序算法。其与直接排序算法最大的区别在于查找插入位置时使用的是二分查找的方式,在速度上有一定提升。


原理


假设前面的都是排好序的列,把你需要插入的值跟前面的数组二分折半位置比较,小的话往前继续二分插入,大就往后二分插入。


算法的实现:



3. 插入排序—希尔排序(Shell`s Sort)



基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

①取定一个正整数d1作为间隔值,把全部记录从第一个记录起进行分组,所有距离为d1倍数的记录放在一组中,在各组内进行直接插入排序。

②取定一个正整数d2,重复上述分组和排序工作,直至取di=1为止,即所有记录在一个组中进行直接插入排序。

③希尔提出的方法是:d1=n/2,di+1=d1/2


实例说明:对序列{25,36,12,68,45,16,37,22 }进行希尔排序。




算法的实现:




4. 选择排序—简单选择排序(Simple Selection Sort)


基本思想:在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。


示例:


算法的实现:




5. 选择排序—堆排序(Heap Sort)


基本思想:

(1)把待排序数组构造成一个最大堆

(2)取出树的根(最大(小)值, 实际算法的实现并不是真正的取出)

(3)将树中剩下的元素再构造成一个最大堆(这里的构造和第1步不一样,具体看实现部分)

(4)重复2,3操作,直到取完所有的元素

(5)把元素按取出的顺序排列,即得到一个有序数组(在代码实现里是通过交换操作"无形中"完成的)

在开始实现算法先看几个结论(证明略):

(1)完全二叉树A[0:n-1]中的任意节点,其下标为 ii, 那么其子节点的下标分别是为2i+12i+1 和 2(i+1)2(i+1)

(2)大小为n的完全二叉树A[0:n-1],叶子节点中下标最小的是⌊n2⌋⌊n2⌋, 非叶子节点中下标最大的是⌊n2⌋−1⌊n2⌋−1

(3)如果数组是一个最大堆,那么最大元素就是A[0]

(4)最大堆中任意节点的左右子树也是最大堆



6. 交换排序—冒泡排序(Bubble Sort)


基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。


示例:


算法实现:



7. 交换排序—快速排序(Quick Sort)


基本思想:

1)选择一个基准元素,通常选择第一个元素或者最后一个元素,

2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。

3)此时基准元素在其排好序后的正确位置

4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。


示例:

(a)一趟排序的过程:


(b)排序的全过程


算法的实现:



8. 归并排序(Merge Sort)


基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

示例:


算法实现:

你可能感兴趣的:(C语言----排序算法)