c语言排序方法汇总

C语言排序方法汇总

二级目录

 在接下来的排序方法中,我们都采用4 1 2 6 5 3这个数列作为我们的栗子

一 冒泡排序

412653
1124536
2124356
3123456
4123456
5123456

 冒泡排序的本质就是每次将前n-i个数中的最大值换到第n-i+1位上去
代码如下

 for (int i=1; i<=n; i++) {
       for (int j=1; j<=n-i; j++) {
           if(a[j+1]<a[j]) swap(&a[j+1],&a[j]);
        }

优点:写起来简单
缺点:运算量过大每两个之间就要比较一次

二 快速排序

 选择排序的重点在于设置一个基准值,将数列分为大于基准值和小于基准值的两个部分,再对两个部分重复操作,递归求解,这里将初始基准值设为2

412653
1214653
2124356
3123456

第 一 次 : 1 − 6 第 二 次 : 1 − 2 3 − 6 第 三 次 : 3 − 4 5 − 6 第一次:1-6\\ 第二次 :1-2 \quad 3-6\\ 第三次: 3-4 \quad5-6 16:12363456

void quicksort(int left,int right)
{
    int mid=a[(left+right)/2];
    int i=left;
    int j=right;
    while(i<=j){
        while(a[i]<mid) i++;
        while(a[j]>mid) j--;
        if(i<=j) {swap(&a[i],&a[j]);i++;j--;}
    }
    if(i<right) quicksort(i,right);
    if(j>left) quicksort(left, j);
}

优点:运行速度较快
缺点:不稳定,在一些情况下可能会较慢(但肯定比冒泡快很多)

三 选择排序

 即从n个数中取出最小的数,和第一位的数进行 交换,再对n-1个数重复操作

412653
1142653
2124653
3123465
4123465
5123456

 这种方法其实和冒泡的差别不大,只是减少了交换的次数,对冒泡进行了优化。

void choosesort()
{
    for (int i=1; i<=n; i++) {
        int minn=a[i], minx=i;
        for (int j=i; j<=n; j++) {
          if(a[j]<minn){minn=a[j];minx=j;}
        }
        swap(&a[i], &a[minx]);
    }
}

四 插入排序

即将数列分为两个数列,一个为有序的,另一个为无序

初始4 1 2 6 5 3

不断将无序的数列插入到有序的数列中去

41 2 6 5 3
1 42 6 5 3

以此类推

412653
142653
124653
124563
123456
void StraightSort(int len)
{
    int tmp;
    int i;
    int j;
    for (i = 1;i<=len;i++)
    {
        tmp = a[i];
        for (j = i-1;j >= 1 && a[j] > tmp;j--)
        {
            a[j + 1] = a[j];
        }
        a[j + 1] = tmp;
    }
}

优点:插入排序在数组量较小,数据较为整齐时速度较快
缺点:不稳定,若是出现较小的数字在靠后的位置,则会增加运算的复杂性(所以出现了希尔(shell)排序

五 希尔排序

 为了更好的说明希尔排序,我们是用一组较为极端的数据

7 4 3 2 5 6 1 8

如果进行插入排序,如下

74325618
47325618
34725618
23475618
23457618
手累了-_-

我们要进行很多次的插入,比较,交换…所以不如先交换一些数据,使得数组更加整齐

74325618
14325678

有序性大大提高,便于插入排序

进入正文

 在希尔排序中,我们从数组中按照一定的间距取出一个数组,对它进行排序,直至最终间距为1,即正常的插入排序

按照一定的间隔进行插入排序

void insert(int start,int gap,int len)
{
    int i,j;
    for (i=start; i<=len; i+=gap) {
        int temp=a[i];
        for (j=i-gap; j>=0&&a[j]>temp; j-=gap) {
            a[j+gap]=a[j];
        }
        a[j+gap]=temp;
    }
}

让初始值为 l e n 2 \frac {len} {2} 2len,再不断缩小

void shellsort(int len)
{
    for (int i=len/2; i>=1; i/=2) {
        for (int j=0; j<=i-1; j++) {
            insert(j, i, len);
        }
    }
}
// 完整版的shell排序
void shellSort(int* a,int len)
{
  for(int gap=len/2;gap>0;gap/=2)
  {   
   //对于hk(即gap),hk+1,...,N-1中的每个位置i,把位置i上的元素放到i,i-hk,i-2hk......中的正确位置上
    for(int i=gap;i<len;++i)
    {
      int tmp=a[i];
      int j=i;
      for(;j>=gap&&tmp<a[j-gap];j-=gap)
      {
        a[j]=a[j-gap];
      }
      a[j]=tmp;
    }          
}

优化了插入排序

先更新到这里,之后会持续更新
三连再看,月入百万。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值