who knows the truth。
Fork me on GitHub
返回顶部

三种排序比较

1.冒泡排序

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 

 算法描述

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 重复步骤1~3,直到排序完成。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define N 10000
int a[N];
void bubblesort(int);
void swap(int,int);
int main(void)
{
    int i,n;
    scanf("%d",&n);
    srand((unsigned)time(NULL));
    for(i=0;i<n;i++)
    {
        a[i]=rand()%100;
        printf("%d ",a[i]);
    }
    printf("\n");
    bubblesort(n);
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;

}
void bubblesort(int num)
{
    int i,j;
    for(i=0;i<num-1;i++)
        for(j=0;j<num-i-1;j++)
    {
        if(a[j]>a[j+1])
            swap(j+1,j);
    }
    return;
}
void swap(int i,int j)
{
    int temp;
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
    return;
}

冒泡排序平均时间复杂度

O(n2).

注意:冒泡排序每排一次得到最大值,最小值慢慢往左移

2.快速排序

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

 算法描述

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

 

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define N 10000
int a[N];
void quicksort(int,int);
int partition(int,int);
void swap(int,int);
int main(void)
{
    int i,n;
    scanf("%d",&n);
    srand((unsigned)time(NULL));
    for(i=0;i<n;i++)
    {
        a[i]=rand()%100;
        printf("%d ",a[i]);
    }
    printf("\n");
    quicksort(0,n-1);
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;

}
void quicksort(int low,int high)
{
   if(low<high)
   {
       int i;
       i=partition(low,high);
       quicksort(low,i-1);
       quicksort(i+1,high);
   }
   return;
}
int partition(int low,int high)
{
    int i,j,pivot;
    i=low;
    j=high;
    pivot=a[low];
    while(i<j)
        {
        while(i<j&&a[j]>=pivot)
            j--;
        while(i<j&&a[i]<=pivot)
            i++;
        if(i<j)
            swap(i,j);
        }
        swap(low,i);
        return i;
}
void swap(int i,int j)
{
    int temp;
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
    return;
}

partiton(int,int)每次找出一个基值,在基值左边的数都小于基值,右边的数大于基值。

在quicksort(int)递归地分别排序

平均时间复杂度O(nlogn)

3.归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。 

  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define N 10000
int a[N];
void mergesort(int,int);
void merge(int,int,int);
int main(void)
{
    int i,n;
    scanf("%d",&n);
    srand((unsigned)time(NULL));
    for(i=0;i<n;i++)
    {
        a[i]=rand()%100;
        printf("%d ",a[i]);
    }
    printf("\n");
    mergesort(0,n-1);
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;

}
void mergesort(int low,int high)
{
   if(low<high)
   {
       int mid=(high-low)/2+low;
       mergesort(low,mid);
       mergesort(mid+1,high);
       merge(low,mid,high);
   }
   return;
}
void merge(int low,int mid,int high)
{
    int i=low;
    int j=mid+1;
    int k=0;
    int *tmp;
    tmp=(int*)malloc((high-low+1)*sizeof(int));
    while(i<=mid&&j<=high)
        (a[i]>a[j])?(tmp[k++]=a[j++]):(tmp[k++]=a[i++]);
      while(i<=mid)
        tmp[k++]=a[i++];
        while(j<=high)
            tmp[k++]=a[j++];
        for(k=0,i=low;i<=high;k++,i++)
            a[i]=tmp[k];
        free(tmp);
        return;
}

平均时间复杂度O(nlogn)

需要分配动态空间

 

posted @ 2020-10-09 16:28  no_sense  阅读(240)  评论(0编辑  收藏  举报
欢迎来到kanashimi的博客
pic
kanashimi
真理将引领我们