c语言----003(冒泡排序和选择排序)

一:冒泡排序

排序原理

以升序排列为例
(1)从左到右,依次比较相邻的两个变量
(2)若a[i]>a[i+1],交换a[i]与a[i+1]的值,i++后重复上述比较与交换
(3)就这样一趟一趟的比较,每一趟右边得到相对最大的值,像冒泡一样
(4)一个容量为n的数组就要走n-1趟,故时间复杂度为o(n^2)

代码示例

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num[12]={5,6,8,4,2,6,45,2,23,4,45,28};
    for(int i=0;i<11;i++)//控制遍历次数
    {
        for(int j=0;j<11;j++)//比较相临值,交换
        {
            if(num[j]>num[j+1])
            {
                int temp=num[j];
                num[j]=num[j+1];
                num[j+1]=temp;
            }
        }
    }
    for(int i=0;i<12;i++)
    {
        printf("%d ",num[i]);
    }
    printf("\nHello world!\n");
    return 0;
}

优化

优化原理

注意到,第( i+1 )趟循环结束,右边(i+1)个数已经是排的相对于剩下数最大的了,因此,这一部分不在需要排序,下面代码示例,更直观的感受一一下。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num[12]= {5,6,8,4,2,6,45,2,23,4,45,28};
    for(int i=0; i<11; i++) //控制遍历次数
    {
        for(int j=0; j<11; j++) //比较相临值,交换
        {
            if(num[j]>num[j+1])
            {
                int temp=num[j];
                num[j]=num[j+1];
                num[j+1]=temp;
            }
        }
        printf("第%2d次循环",i+1);
        for(int i=0; i<12; i++)
        {
            printf("%d ",num[i]);
        }
        printf("\n");
    }

    printf("\nHello world!\n");
    return 0;
}

/*运行结果
第 1次循环5 6 4 2 6 8 2 23 4 45 28 45
第 2次循环5 4 2 6 6 2 8 4 23 28 45 45
第 3次循环4 2 5 6 2 6 4 8 23 28 45 45
第 4次循环2 4 5 2 6 4 6 8 23 28 45 45
第 5次循环2 4 2 5 4 6 6 8 23 28 45 45
第 6次循环2 2 4 4 5 6 6 8 23 28 45 45
第 7次循环2 2 4 4 5 6 6 8 23 28 45 45
第 8次循环2 2 4 4 5 6 6 8 23 28 45 45
第 9次循环2 2 4 4 5 6 6 8 23 28 45 45
第10次循环2 2 4 4 5 6 6 8 23 28 45 45
第11次循环2 2 4 4 5 6 6 8 23 28 45 45
*/

然后我们又发现第六次循环时其实就已经排好了序,这时候我们可以判断是否交换了值,未交换值说明已经排好了,结束循环

优化后代码

#include<stdio.h>
int main()
{
    int num[12]= {5,6,8,4,2,6,45,2,23,4,45,28};
    int flag;//用于判断是否交换的标记
    for(int i=0;i<11;i++)
    {
        flag=1;
        for(int j=0;j<11-i;j++)
        {
            if(num[j]>num[j+1])
            {
                int temp=num[j];
                num[j]=num[j+1];
                num[j+1]=temp;
                flag=0;
            }
        }
        printf("第%2d趟排序",i+1);
        for(int i=0;i<12;i++)
        {
            printf("%d ",num[i]);
        }
        printf("\n");
        if(flag)
        {
            break;
        }
    }
    for(int i=0;i<12;i++)
    {
        printf("%d ",num[i]);
    }
    return 0;
}

/*
第 1趟排序5 6 4 2 6 8 2 23 4 45 28 45
第 2趟排序5 4 2 6 6 2 8 4 23 28 45 45
第 3趟排序4 2 5 6 2 6 4 8 23 28 45 45
第 4趟排序2 4 5 2 6 4 6 8 23 28 45 45
第 5趟排序2 4 2 5 4 6 6 8 23 28 45 45
第 6趟排序2 2 4 4 5 6 6 8 23 28 45 45
第 7趟排序2 2 4 4 5 6 6 8 23 28 45 45
2 2 4 4 5 6 6 8 23 28 45 45
*/

二:选择排序

排序原理

(1)顾名思义,选择排序就是每回选择最大或者最小的数和每一趟开始的数交换值
(2)一般设置一个盯哨,记录最大值所在位置,以数组为例,记录数组下标

代码示例

#include<stdio.h>

void print(int num[],int n)
{
    for(int i=0; i<n; i++)
    {
        printf("%d ",num[i]);
    }
    printf("\n");
}

void swap(int*m,int*n)
{
    int temp;
    temp=*m;
    *m=*n;
    *n=temp;
}

int main()
{
    int num[12]= {12,45,56,78,45,15,14,54,5,45,1,23};
    int temp;//监视哨
    for(int i=0; i<11; i++)
    {
        temp=i;
        for(int j=i+1; j<12; j++)
        {
            if(num[temp]<num[j])
            {
                temp=j;
            }
        }
        swap(&num[temp],&num[i]);
    }
    print(num,12);
    return 0;
}


优化

优化原理

我们可以同时选择最大和最小的数,两边同时进行

优化后代码

//优化选择排序
{12,45,56,78,45,15,14,54,5,45,1,23}
//对以上数组排序



#include <stdio.h>
void print(int num[],int n)
{
    for(int i=0;i<n;i++)
    {
        printf("%d ",num[i]);
    }
    printf("\n");
}

void Swap(int *m,int *n)
{
    int temp;
    temp=*m;
    *m=*n;
    *n=temp;
}

int main()
{
    int num[12]={12,45,56,78,45,15,14,54,5,45,1,23};
    int Max,Min;//监视哨
    for(int i=0,j=11;i<5;i++,j--)
    {
        Max=i;
        Min=i;
        for(int j=i+1;j<12-i;j++)
        {
            if(num[Max]<num[j])
            {
                Max=j;
            }
            if(num[Min]>num[j])
            {
                Min=j;
            }
        }
        Swap(&num[Max],&num[i]);
        Swap(&num[Min],&num[j]);
    }
    print(num,12);
    return 0;
}

总结

突然发现C语言好像不能引用传参,另外,后面的代码计划用C++编写,个人认为都差不多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惜日短

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值