八种常用的排序方法

八种常用的排序方法


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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值