基于C语言的八大排序算法的比较

Sametime

发布日期: 2018-10-31 22:30:04 浏览量: 1012
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

一、项目内容

将冒泡排序,选择排序,直接插入排序,希尔排序,快速排序,堆排序,归并排序,基数排序等八种排序方法做横向比较,针对相同的随机数据,比较排序算法所消耗的时间以及交换次数。

二、算法描述

2.1 冒泡排序

算法描述:

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数

  • 针对所有的元素重复以上的步骤,除了最后一个

  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

2.2 选择排序

算法描述:

对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较如果后面的元素比他要小则用变量k记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小的数了。然后找到数组中第二小的数,让他跟数组中第二个元素交换一下值,以此类推。

2.3 直接插入排序

算法描述:

每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

2.4 希尔排序

算法描述:

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

2.5 快速排序

算法描述:

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

  1. 设置两个变量i、j,排序开始的时候:i=0,j=N-1

  2. 以第一个数组元素作为关键数据,赋值给key,即key=A[0]

  3. 从j开始向前搜索,即由后开始向前搜索(j—),找到第一个小于key的值A[j],将A[j]赋给A[i]

  4. 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]赋给A[j]

  5. 重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)

2.6 堆排序

堆的定义:n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):

ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n)(当然,这是小根堆,大根堆则换成>=号)。

算法描述:

  • 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区

  • 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key

  • 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆,直到无序区只有一个元素为止

2.7 归并排序

定义归并操作:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
    比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

  3. 重复步骤3直到某一指针到达序列尾

  4. 将另一序列剩下的所有元素直接复制到合并序列尾

算法描述:

对于无序数组d1,d2,d3,…,dn,递归操作,将d1..dn/2排序,再将dn/2+1..dn排序,然后对两个有序数组进行归并操作,得到有序数组d。

2.8 基数排序

算法描述:

将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

三、算法分析

3.1 冒泡排序

  • 冒泡排序的最坏时间复杂度为O(n^2)

  • 冒泡排序的平均时间复杂度为O(n^2)

3.2 选择排序

  • 选择排序的最坏时间复杂度为O(n^2)。

  • 选择排序的平均时间复杂度为O(n^2)。

3.3 直接插入排序

  • 直接插入排序的最坏时间复杂度为O(n^2)

  • 直接插入排序的平均时间复杂度为O(n^2)

3.4 希尔排序

  • 希尔排序的最坏时间复杂度为O(n^2)

  • 希尔排序的平均时间复杂度为O(n log ^2 n)

3.5 快速排序

  • 快速排序的最坏时间复杂度为O(n^2)

  • 快速排序的平均时间复杂度为O(n log n)

3.6 堆排序

  • 堆排序的最坏时间复杂度为O(n log ^2 n)

  • 堆排序的平均时间复杂度为O(n log n)。

3.7 归并排序

  • 归并排序的最坏时间复杂度为O(n log n)

  • 归并排序的平均时间复杂度为O(n log n)

3.8 基数排序

  • 基数排序的最坏时间复杂度为O(kn)

  • 基数排序的平均时间复杂度为O(kn)。

四、操作说明

  • 进入程序后按照提示输入产生随机数的个数

  • 输入1—8并按回车选择排序算法,选择后程序会输出此算法所用时间和所用交换次数

  • 输入9退出程序

上传的附件 cloud_download 基于C语言的八大排序算法的比较.7z ( 76.60kb, 102次下载 )
error_outline 下载需要7点积分

keyboard_arrow_left上一篇 : 基于C++语言在Linux环境下模拟实现命令解释器 基于C++的分组密码加解密实现 : 下一篇keyboard_arrow_right



Sametime
2018-10-31 22:31:13
使用C语言实现冒泡排序、选择排序、直接插入排序、希尔排序、快速排序、堆排序、归并排序、基数排序等8种排序并比较

发送私信

懒惰有懒惰的好处,勤奋有勤奋的乐趣。重要的是,你有享受过程的权利,就有承担后果的义务

6
文章数
7
评论数
最近文章
eject