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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c_zyer/article/details/60781526

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

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)。

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

展开阅读全文

没有更多推荐了,返回首页