各排序算法介绍及时间复杂度分析

1.排序算法总览

通过任何键比较的算法,其时间复杂度不会优于nlgn。分配排序不是键比较算法。
在这里插入图片描述

2.交换排序(冒泡排序)

算法介绍

所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

void swapsort(int a[])
{
for(int i=1; i<=n; i++){
for(intj=i+1; j<=n; j++){
if(a[i]>a[j]){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}

时间复杂度

For-i执行n遍,在for-i 第一遍时,for-j执行n-1遍,在for-i 第2遍时,for-j执行n-2遍,…,在for-i 最后一遍时,for-j执行0遍.
所以T(n)=(n-1)+(n-2)+…+1+0=(n-1)*n/2.

3.合并排序

算法介绍
即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
在这里插入图片描述
时间复杂度
对于最好,最坏和平均情况,问题都要将规模分解到1为止,所以三者的时间复杂度相同。
   T(n) = 2T(n/2) + θ(n)  n > 1时
   T(n) = θ(1)       n = 1时
通过画递归树分析可知T(n) = cnlgn + cn, 时间复杂度即为θ(nlgn),当然也为o(nlgn)。

4.快速排序

算法介绍

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

5.插入排序

算法介绍
插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

希尔排序(分组插入)

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。该方法因D.L.Shell于1959年提出而得名。
该方法实质上是一种分组插入方法。

6.选择排序

算法介绍
第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零
func SelectionSort(nums []int32) {
length := len(nums)
for i := 0; i < length; i++ {
min := i
for j := i + 1; j < length; j++ {
if nums[j] < nums[min] {
min = j
}
}
temp := nums[i]
nums[i] = nums[min]
nums[min] = temp
}
fmt.Println(nums)
}

时间复杂度
由于仅在for-i底部进行一次交换,故共交换n-1次,而每次交换需要3次赋值,故所有情况(最坏)时间复杂度为3(n-1)。

7.堆排序

算法介绍
堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

Void heapsort(int n ,heap&H){
Makeheap(n,H);
Removekeys(n,H,H.S);
}

算法其实就是不断的构造堆,然后移除根节点。每次移除的根节点都是最大值,所以相当于完成了排序。下图是一个示例。
在这里插入图片描述

8.分配排序(基数排序)

算法介绍
不是键值比较类算法。

比如下面数字,是以10为基数,先排左边第一位,放到不同的堆中;再排左边第二位,最后排左边第三位。所以位数检查完后,就是有序的数列了。如果从最右一位排起也是可以的,道理类似。

在这里插入图片描述

发布了21 篇原创文章 · 获赞 18 · 访问量 1455

猜你喜欢

转载自blog.csdn.net/zephyr_wang/article/details/104264554