排序算法的时间复杂度(总)

下文介绍了一些算法的代码及其时间复杂度的分析:

1、选择排序:不稳定,时间复杂度 O(n^2)
代码样例:

void sel_sort(int *a, size_t size)
{
    int i, j;
    int min_index;
    int t;
    for(i = 0; i < size - 1; i ++){
        min_index = i;
        for( j = i + 1; j < size; j++){
            if(a[j] < a[min_index])
                min_index = j;
        }
        if (min_index != i){
            t = a[i];
            a[i] = a[min_index];
            a[min_index] = t;
        }
    }
}
  • 外层为0时,内层需要走N-1次,外层为1时,内层需要走N-2次,……外层为N-2时,内层为1次,共比较的次数是 (N - 1) + (N - 2) + … + 1,得 (N - 1 + 1)* (N-1) / 2 = N^2 / 2;
  • 其时间复杂度为 O(N^2);

2、插入排序:稳定,时间复杂度 O(n^2)
代码样例:

void insertion_sort(int *a, size_t size)
{
    int i, j, t;
    for(i = 1; i < size; i++){
        t = a[i];
        j = i - 1;
        while(j >= 0){
            if(a[j] > t){
                a[j + 1] = a[j];
            }
            else
                break;
            j--;
        }
        j += 1;
        a[j] = t;
    }
}
  • 最坏情况,数组完全逆序,插入第2个元素时要与前1个元素比较,……,插入第N个元素,要与前 N - 1 个元素比较;
    因此,最坏情况下的比较次数是 1 + 2 + 3 + … + (N - 1),求和结果为 N^2-N /2;
    所以最坏情况下的复杂度为 O(N^2)。

  • 最好情况,数组已经是有序的,每插入一个元素,只需要与前一个元素比较一次,因此最好情况下,插入排序的时间复杂度为O(N)

3、冒泡排序:稳定,时间复杂度 O(n^2)
代码样例:

void bubble_sort(int *a, int size)
{
  int i, j, temp;
  for(i = 1; i < size; ++i){
    for(j = 0; j < size -i; ++j){
      if(a[j] > a[j+1]){
        temp = a[j];
        a[j] = a[j+1];
        a[j+1] = temp;
      }
    } 
  }
}
  • 其外层循环执行 N - 1次;
  • 内层循环最多的时候执行N次,最少的时候执行1次,平均执行 (N+1)/2次;
  • 所以循环体内的比较交换约执行 (N - 1)(N + 1) / 2 = (N^2 - 1)/2;
  • 复杂度为O(N^2)。

4、堆排序:不稳定,时间复杂度 O(nlog n)

堆排序在最坏的情况下,其时间复杂度也为O(nlogn);
相对于快速排序来说,这是堆排序的最大优点;
此外,堆排序仅需一个记录大小的供交换用的辅助存储空间。

5、归并排序:稳定,时间复杂度 O(nlog n)

#include<iostream.h>
voidMerge(intr[],intr1[],ints,intm,intt){
inti=s;
intj=m+1;
intk=s;
while(i<=m&&j<=t){
if(r[i]<=r[j])
r1[k++]=r[i++];
else
r1[k++]=r[j++];
}
if(i<=m)
while(i<=m)
r1[k++]=r[i++];
else
while(j<=t)
r1[k++]=r[j++];
for(intn=s;n<=t;n++)
r[n]=r1[n];
}

voidMergeSort(intr[],intr1[],ints,intt){
if(s<t){
intm=(s+t)/2;
MergeSort(r,r1,s,m);
MergeSort(r,r1,m+1,t);
Merge(r,r1,s,m,t);
}
}
voidmain(){
intr[8]={10,3,5,1,9,34,54,565},r1[8];
MergeSort(r,r1,0,7);
for(intq=0;q<8;q++)
cout<<""<<r[q];
return0;
}
  • 归并排序是指将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(或有序表)。这样的排序方法经常用于多个有序的数据文件归并成一个有序的数据文件;
  • 归并排序比较占用内存,但却是一种效率高且稳定的算法。

6、快速排序:不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2)

  • 理想状况下,每一次都将待排序数组划分成等长两个部分,则需要logn次划分;

  • 最坏情况下,即数组已经有序或大致有序的情况下,每次划分只能减少一个元素,快速排序将退化为冒泡排序,所以时间复杂度最优为O(nlogn),最坏为O(n^2);

  • 在实际应用中,快速排序的平均时间复杂度为O(nlogn)。

【附录】算法比较表格
算法比较

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c_zyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值