八种常用的排序方法

来源:互联网 发布:斑马梦龙网络计划心得 编辑:程序博客网 时间:2024/05/17 13:14

八种常用的排序方法


1.插入排序——直接插入排序(Straight Insertion Sort)

算法:

将一个无序的数组,以第一个记录作为有序,然后进行排序。(在这里就以升叙为例子)设有i个记录是一个有序的数列,则从i+1个记录如果大于i个记录就继续,如果小于的话就往前继续比较直至发现一个比它小的,在此之前的记录向前移一位。(这个道理就像打扑克牌时摸牌排序一样。)

代码实现:

#include <stdio.h>int Insertsort(int n,int a[]){    int x,i,j;    for(i=1;i<n;i++){            x=a[i];         //把要排序的一个记录赋值给x            j=i-1;                 while(x<a[j]&&j>=0){a[j+1]=a[j];j--;}   /*找到一个小于等于它的记录,并且把此前的记录向前移动一位。     注意j>=0要写,防止数组溢出*/         a[j+1]=x;          //把x插入到这个记录的右边    }}int main(){    int n;    while(~scanf("%d",&n))          //在这里使用的是多组输入,首先输入记录的个数,再输入记录    {        int i,a[n];        for(i=0;i<n;i++){            scanf("%d",&a[i]);        }        Insertsort(n,a);        for(i=0;i<n;i++){            printf("%d ",a[i]);        }        printf("\n");    }    return 0;}

2.插入排序——希尔排序(Shell`s Sort)

希尔排序(Shell Sort)是插入排序的一种。因D.L.Shell于1959年提出而得名。

算法:

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

算法分析:

1、Shell排序的执行时间要依赖于增量序列的多少,增量序列的选取有很多种,在这里我们用的减半的方式,但所有种类都要保证最后一个增量为1。
2、虽然希尔排序是进行多次的直接插入排序,但是希尔排序的时间性能是优于直接插入排序的。
①当数组初态是有一定顺序时,此时记录移动较少的次数。
②当n比较小的时候,直接排序的复杂度的最好最坏时间差别不大。
③当n比较大时,即增量比较大,分组比较多,当增量比较小时数组也接近有序,所以排序较快。
3、希尔排序是不稳定的

代码实现:

#include <stdio.h>int Shell_InsertSort(int a[], int n, int dk){    int x,i,j;    for(i=dk;i<n;i++){        j = i-dk;        x = a[i];                   while(x < a[j]&&j>=0){a[j+dk] = a[j];j -= dk;}        a[j+dk] = x;               }}//这里不在进行过多的解释,利用的就是直接插入排序。int Shellsort(int a[], int n){    int dk = n/2;    while( dk >= 1  ){        Shell_InsertSort(a, n, dk);        dk = dk/2;    }}//每次的增量除以二,直到增量为一int main(){    int n;    while(~scanf("%d",&n))    {        int i,a[n];        for(i=0;i<n;i++){            scanf("%d",&a[i]);        }        Shellsort(a,n);        for(i=0;i<n;i++){            printf("%d ",a[i]);        }        printf("\n");    }    return 0;}

3.交换排序——冒泡排序

冒泡排序也是我学习排序时学习的第一种排序,这种排序就像排气泡一样,比较两个气泡的大小,根据气泡的大小来排序,只要发现有违背一定规则的气泡,就改变气泡的位置,如此反复,即可排好顺序。

算法:

对于一组无序数组,进行多次扫描(我们依旧是做升序)。
第1次扫描:通过两两比较,交换位置找出最大的气泡,并让他沉到最下面(即将此记录放到最右边)。
第2次扫描:找出“次重”的气泡,让他沉到最大气泡的上面
……
……
第n-1次扫描:经过重新的排序,此时数组成为一个升序数组了。
冒泡排序其实就是将记录从大到小依次找出,每找出一个记录就将其排出顺序。

代码实现:

#include <stdio.h>int Bubblesort(int n,int a[]){    int i,j,tmp;    for(i=n-2;i>=0;i--){   //注意:这里i要从n-2开始取值,n-2到0为n-1次扫描        for(j=0;j<=i;j++){ //之所以从n-2开始是因为如果j=i,要注意j+1不能越界            if(a[j]>a[j+1]){tmp=a[j];a[j]=a[j+1];a[j+1]=tmp;}    //利用中间值tmp将两个记录交换        }    }}/*在我开始使用冒泡排序时,我经常犯得一个错误就是数组越界,所以一定要注意进行第一次时数组是否越界*/int main(){    int n;    while(~scanf("%d",&n))    {        int a[n],i;        for(i=0;i<n;i++){                scanf("%d",&a[i]);        }        Bubblesort(n,a);        for(i=0;i<n;i++){                printf("%d ",a[i]);        }        printf("\n");    }    return 0;}

0 0
原创粉丝点击