排序算法之冒泡排序

问题描述:

输入一个原始数列,把它进行升序排序,从小到大输出。

例如:给定数列如下:
5 15 99 45 12 1 90 19 33 41

排序后的结果为:
1 5 12 15 19 33 41 45 90 99

冒泡排序顾名思义,就是让小的数一个一个的冒到上面来(最上面就是我们数组下标0),那么具体的做法是,从后往前两两进行比较,让两者中较小往上升,大家看一下下面这个过程:

下标值序号: 0 1 2 3 4 5 6 7 8 9
原始状态为: 5 15 99 45 12 1 90 19 33 41
第一趟排序: 1 5 15 99 45 12 19 90 33 41(遍历下标0-9,比较相邻的两个数,把小的交换到前面去)
第二趟排序: 1 5 12 15 99 45 19 33 90 41(遍历下标1-9,比较相邻的两个数,把小的交换到前面去)
第三趟排序: 1 5 12 15 19 99 45 33 41 90(遍历下标2-9,比较相邻的两个数,把小的交换到前面去)
第四趟排序: 1 5 12 15 19 33 99 45 41 90(遍历下标3-9,比较相邻的两个数,把小的交换到前面去)
第五趟排序: 1 5 12 15 19 33 41 99 45 90(遍历下标4-9,比较相邻的两个数,把小的交换到前面去)
第六趟排序: 1 5 12 15 19 33 41 45 99 90(遍历下标5-9,比较相邻的两个数,把小的交换到前面去)
第七趟排序: 1 5 12 15 19 33 41 45 90 99(遍历下标6-9,比较相邻的两个数,把小的交换到前面去)

大家可以看到,当我们完成第七趟排序之后,数列已经完全有序了,从这里我们可以发现:
1. 理论上来说,如果数列有N个数,最坏的情况下,需要N-1趟才能完全排好(因为每一趟一定能排好一个数)
2. 在大多数情况下,我们都可以小于N-1趟完成排序
3. 由上面的分析可以看出,本来以为需要9趟才能完成,现在7趟就已经完成了任务了,那么接下来我们就可以退出了,不必再做无用功了
4. 这个算法的时间复杂度是O(n^2)

参考代码:

#include<stdio.h>

int main()
{
    int arr[] = { 5, 15, 99, 45, 12, 1, 90, 19, 33, 41 };
    int i, j, nTemp, nIsAllSoft, nCount = sizeof(arr) / sizeof(arr[0]);
    printf("排序前\n");
    for (i = 0; i < nCount; i++)
        printf("%d ", arr[i]);
    printf("\n");

    for (i = 0; i < nCount; i++)
    {
        nIsAllSoft = 1;//假定开始全部排好了,用C语言实现的,里面没有bool,也不想用char,就用int表示算了
        for (j = nCount - 1; j > i; j--)//每次完成循环就至少排好了一个数,从下标为0开始
        {
            if (arr[j] < arr[j  - 1])
            {
                nTemp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = nTemp;
                nIsAllSoft = 0;//因为有交换所以没有排好
            }
        }
        if (nIsAllSoft == 1)
            break;
    }

    printf("\n排序后\n");
    for (i = 0; i < nCount; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值