冒泡排序

周末闲着整理一下以前的资料,好记性不如烂笔头,也是个回顾的过程。

1.简述

冒泡排序呢,属于相邻元素比较的一种排序方法;
相邻元素根据大小换位置,从头换到尾,就逐渐把比较大的元素换到了后边。

2.原理呢

就是通过一轮轮的比较,在每一轮中获取这个数据中当前轮最大/小的元素,若前一个数大于/小于后一个数,则交换位置,如下:

第一轮比较:获取当前轮最大/小值,这个值也是咱们数据中的最大/小值;
第二轮比较:获取当前轮最大/小值,这个值是仅次于第一轮获取的数据;
。。。。
第n轮比较:获取的当前轮最大/小值,这个值也是容量为n的数据中最大/小的值了;

我自己的理解呢,就是可以把这些数据看作一团液体,每一轮的冒泡判断呢,就好比从这个液体中抠出去一部分,而要抠出去的是最大的一坨呢还是最小的一坨,这个无所谓,反正每一轮过后液体体积就减少了,从而下一轮我们要比较的次数也少了。

举个例子:数据{ 20, 40, 8, 96, 32, 12, 45, 67},容量n为8,按照升序排序:

第一轮:
要比较的是全部n个数据,这一轮就能获取到最大的值96,第一轮过后数据内容变为:
20,8,40,32,12,45,67,96  从而抠出来了最大的96;
第二轮:
需比较的元素个数减一(n-1),这一轮获取最大值次之元素,67,第二轮过后数据内容变为:
8,20,32,12,40,45,67,96   抠出来了67;
第三轮:
需比较元素个数再减一(n-2),获取到45,第三轮过后数据内容变为:
8,20,12,32,40,45,67,96   抠出来了45;
第四轮:
需比较元素个数再减一(n-3),获取到40,第四轮过后数据内容变为:
8,12,20,32,40,45,67,96   抠出来了40;
第五轮:
需比较元素个数再减一(n-4),获取到32,第五轮过后数据内容变为:
8,12,20,32,40,45,67,96   抠出来了32;
第六轮:
需比较元素个数再减一(n-5),获取到20,第六轮过后数据内容变为:
8,12,20,32,40,45,67,96   抠出来了20;
第七轮:
需比较元素个数再减一(n-6),获取到12,第七轮过后数据内容变为:
8,12,20,32,40,45,67,96   抠出来了12;
第八轮:
需比较元素个数再减一(n-7),获取到8,第八轮过后数据内容变为:
8,12,20,32,40,45,67,96   抠出来了8;

可以看到,比较轮数与元素总个数相同,每一轮比较的元素个数减少一个,并获取了当前剩余的数据中最大的那个值。
有两点需要注意的是:
(1)下一轮需要比较的元素个数,是总数减去已经抠出来的元素后剩下的;
(2)有n个数进行相邻元素互相比较时,只需要比较n-1次就可以;
稳定性:
稳定性是指数据中若干值相同的元素的相对位置,是否变化;
在冒泡判断过程中,若在小于/大于时才进行换位的情况下,是稳定的;
若小于等于/大于等于时候也进行换位的话,是不稳定的。

3.代码

void bubbleSort(int *array, int size)
{
	if (NULL == array)
	{
		printf("array is NULL.\n");
		return;
	}
	// loopNum表示需要比较的轮数,与元素总数相同
	for (int loopNum = 0; loopNum < size; loopNum++)
	{
	    // 判断条件要注意,每一轮比较时,剩余要比较的元素个数x:x = n-已抠出元素数
	    // 而x个元素相邻比较只需要判断x-1次即可,所以需要设置为如下形式
		for (int cmpInLoop = 0; cmpInLoop < size - loopNum - 1; cmpInLoop++)
		{
		    // 相邻元素左右之间比较
			if (*(array + cmpInLoop) > *(array + cmpInLoop + 1))
			{
				int tmp = *(array + cmpInLoop + 1);
				*(array + cmpInLoop + 1) = *(array + cmpInLoop);
				*(array + cmpInLoop) = tmp;
			}
		}
	}
}

4总结

(1)实现之前一定要知道其原理,并有自己的理解才行;
(2)通过原理部分的比较步骤,可看到在已经有序的情况下冒泡排序还是要循环判断,并且多次重复判断,这是很大的缺点,所以时间复杂度为O(n^2);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值