冒泡,简单选择,直接插入,快速排序,希尔排序,归并排序等几大排序----C语言

一.冒泡排序
思想:每相邻两数进行比较,从第一个数开始,一和二比较,若1比2大交换,在2和3比较,若2比3小不交换,反之交换,同理3和4,4和5,一直n-1和n比较,这样完成一轮得到最大的数放到最后一位。第二轮依然从第一个数开始,1和2,2和3,直到比较到倒数第二位停止(因为最后一位是最大的已经排好),近下来进行第三轮第四轮,一共进行n-1轮(因为第n轮时没有可比较得,故第n-1轮时停止),每轮比较到n-i-1时停止比较。
代码如下:

#define N 10
int main()
{
    int i,j,t,n,a[N];
    printf("请输入数据个数\n");
    scanf("%d",&n);
    printf("请输入数据\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    for(i=0;i<n-1;i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
}
在这里插入代码片

二.简单选择排序
思想:先拿第一个数和它后面的数依次比较,如果第一个比较大,就交换,保证第一个数最小,直到和第n个比较完毕,完成一轮,之后将第二个数和它后面的数开始比较,直到比较到第n个保证第二位最小,同理,一直比较到倒数第二位(因为最后一位没有可比较的数,故不需要比较),一共完成n-1轮。
代码如下:

#define N 10
int main()
{
    int i,j,t,n,a[N];
    printf("请输入数据个数\n");
    scanf("%d",&n);
    printf("请输入数据\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    for(i=0;i<n-1;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(a[i]>a[j])
            {
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
}
在这里插入代码片

三.直接插入排序
思想:假设在第i(i>=1)之前的元素即(0,i-1)都已经排好顺序,本趟需要找到i对应元素x的正确位置k,并且在寻找这个位置k的工程中逐个将比较过的元素后移一位,为元素x腾出一位置插入,最后将k对应元素值赋为x。
代码如下:

#define N 10
int main()
{
    int i,j,t,n,a[N];
    printf("请输入数据个数\n");
    scanf("%d",&n);
    printf("请输入数据\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    for(i=1;i<n;i++)
    {
        t=a[i];
        for(j=i-1;j>-1&&a[j]>t;j--)
        {
            a[j+1]=a[j];
        }
        a[j+1]=t;
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
}
在这里插入代码片

四.快速排序
思想:以一个数为基准,将序列中的其他数往它两边扔,以从小到大为例,比他小的都放在他的左边,比他大的都放在他的右边,然后左右两边再分别重复这个操作,不停地分直到每一个分区的基准数都只有一个数为止。
代码如下:

#define N 10
void swap(int *,int *);
void quicksort(int *,int ,int );
void swap(int *a,int *b)
{
    int t;
    t=*a;
    *a=*b;
    *b=t;
    return;
}
void quicksort(int *a,int low,int high)
{
    int i=low;
    int j=high;
    int k=a[low];
    if(low>=high)
    {
        return;
    }
    while(low<high)
    {
        while(low<high&&k<=a[high])
        {
            --high;
        }
        if(k>a[high])
        {
            swap(&a[low],&a[high]);
            ++low;
        }
        while(low<high&&k>=a[low])
        {
            ++low;
        }
        if(k<a[low])
        {
            swap(&a[low],&a[high]);
            --high;
        }
    }
    quicksort(a,i,low-1);
    quicksort(a,low+1,j);
}
int main(void)
{
    int i,j,n,a[N];
    printf("请输入数据\n");
    scanf("%d",&n);
    printf("请输入数据\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    quicksort(a,0,n-1);
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}
在这里插入代码片

五.希尔排序
思想:先把需要排序的序列分成若干组,对这若干组进行插入排序,这样就有一部分有序,之后对这个组再重新划分成若干组,再次进行插入排序,直到分组为1时,退出。
为了方便理解,我举以下例子作为参考
设定一个数组为a[]={1,34,6,21,98,31,7,4,36,16,47,67,37,25},该数组长度为n=14;
第一次分d=n/2=7组,得到以下情况

14
3436
616
2147
9867
3137
725

先组内排序为:{1,4},{34,36},{6,16},{21,47},{67,98},{31,37},{7,25}
然后继续分成d=d/2=3组,再次进行直接插入法排序,然后继续执行分组操作,直到分成一组(d=1)后,该排序基本完成了。
代码如下:

#define N 10
int main()
{
    int i,j,t,n,a[N];
    printf("请输入数据个数\n");
    scanf("%d",&n);
    printf("请输入数据\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);   
    }
    int d=n,x;
    while(1)
    {
        d=d/2;
        for(x=0;x<d;x++)
        {
            for(i=x+d;i<n;i=i+d)
            {
                int k=i;
                int t=a[k];
                for(j=i-d;j>-1&&a[j]>t;j=j-d)
                {
                    a[j+d]=a[j];
                    k=j;
                }
                a[k]=t;
            }
        }
        if(d==1)
        {
            break;
        }
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}
在这里插入代码片

六.归并排序
思想:归并排序将待排序的元素分成两个长度相等的子序列,分别为每一个子序列排序,然后把子序列合并成一个总的序列。合并两个子序列的过程称为二路归并。
下面是个思路图:
在这里插入图片描述代码如下:

#define N 10
int merge(int r[],int s[],int x1,int x2,int x3) //将左右两个区域的数进行比较,使较小的数放在左区域
{
    int i,j,k;
    i=x1;       //第一部分的起始位置
    j=x2+1;     //第二部分的起始位置
    k=x1;
    while((i<=x2)&&(j<=x3))        //当i和j在两个要合并的部分时
    {
        if(r[i]<=r[j])          //筛选较小的元素放在数组s中
        {
            s[k]=r[i];
            i++;
            k++;
        }
        else
        {
            s[k]=r[j];
            j++;
            k++;
        }
    }
        while(i<=x2)            //将x1~x2范围中的未比较的元素依次放进数组r中
        {
            s[k++]=r[i++];
        }
        while(j<=x3)           //将x2+1~x3范围中的未比较的元素依次加到数组r中
        {
            s[k++]=r[j++];
        }
    return 0;
}
int merge_sort(int r[],int s[],int m,int n)
{
    int p;
    int t[20];
    if(m==n)
    {
        s[m]=r[m];
    }
    else
    {
        p=(m+n)/2;
        merge_sort(r,t,m,p);    //递归调用merge_sort函数将r[m]~r[p]归并成有序的t[m]~t[p]
        merge_sort(r,t,p+1,n);  //递归调用merge_sort()函数将r[p+1]~r[n]归并成有序的t[p+1]~t[n]
        merge(t,s,m,p,n);       //调用函数将前两部分归并到s[m]~s[n]
    }
    return 0;
}
int main()
{
    int n,a[N],i;
    printf("请输入数据个数\n");
    scanf("%d",&n);
    printf("请输入数据个数\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    merge_sort(a,a,0,n-1);
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}
在这里插入代码片

六种排序介绍完毕,接下来陆续会增添一些诸如二分排序,桶排序等。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值