基于冒泡排序的算法研究

本文详细介绍了冒泡排序的原理,包括确定趟数、一趟冒泡排序的内容及如何减少比较次数。通过实例和代码展示,阐述了如何优化冒泡排序算法,减少不必要的比较。并进一步扩展了冒泡排序,使其能够适用于整型、浮点型以及结构体类型的数组排序,详细给出了每种类型的实现方式。
摘要由CSDN通过智能技术生成

 冒泡排序:将一个无序数组排序成有序数组(升序/降序)

时间复杂度O(n²)

空间复杂度O(1)  

int nums[] = { 3,5,7,1,2,8,9,4,6,10 };

首先随机初始化一个无序数组 这里统一将它调整为升序(降序同理)

int main()
{
	int nums[] = { 3,5,7,1,2,8,9,4,6,10 };
	int numsSize = sizeof(nums) / sizeof(nums[0]);

	int i = 0;
	for (i = 0; i < numsSize; i++)
	{
		printf("%d ", nums[i]);
	}

	printf("\n");
	bubble_sort(nums,numsSize);

	for (i = 0; i < numsSize; i++)
	{
		printf("%d ", nums[i]);
	}

	return 0;
}

 在冒泡排序前后分别打印一次数组 ,对比冒泡排序前后数组的变化。

接下来定义冒泡排序函数主体

void bubble_sort(int* nums,int numsSize)
{
	int i = 0;
	for (i = 0; i < numsSize - 1; i++)//确定冒泡排序趟数
	{
		//定义每一趟冒泡排序具体内容
		int j = 0;
		int flag = 1;//假设这趟冒泡排序已经有序
		for (j = 0; j < numsSize - 1 - i; j++)//两两比较次数为numsSize-1-i次
		{
			if (nums[j] > nums[j + 1])
			{
				int tmp = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag == 1)//如果flag == 1 说明此时数组已经有序
			break;
	}
}

 其实冒泡排序的核心内容就是交换两个变量的值

参考基于交换变量的值的研究_lovepotato_的博客-CSDN博客

这里来讲一讲如何减少两两比较的次数


目录

1.首先要确定冒泡排序的趟数

2.定义一趟冒泡排序的具体内容

3.减少比较次数


1.首先要确定冒泡排序的趟数

趟数最多是 (数组元素个数 - 1) 次。为什么是最多呢 

这里假设一个数组是完全倒序的 把它排成升序(例如如下这个数组)

int nums[] = { 9,8,7,6,5,4,3,2,1 };

 从i = 0 开始 第一趟冒泡排序的实际上就是把 9 一直移动到最后 其余元素相对顺序不变

int nums[] = { 8,7,6,5,4,3,2,1,9 };

同理 第二趟冒泡排序把 8 移动到倒数第二个位置  依次类推

排到最后会发现 最后两个元素(1和2)的顺序是一趟冒泡排序中排好的,所以次数是numsSize - 1次

这就是次数最多的情况。

2.定义一趟冒泡排序的具体内容

	//定义每一趟冒泡排序具体内容
		int j = 0;
		int flag = 1;//假设这趟冒泡排序已经有序
		for (j = 0; j < numsSize - 1 - i; j++)//两两比较次数为numsSize-1-i次
		{
			if (nums[j] > nums[j + 1])
			{
				int tmp = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag == 1)//如果flag == 1 说明此时数组已经有序
			break;

这里有个小坑 内存for循环的循环次数是numsSize-1-i次 

for (j = 0; j < numsSize - 1 - i; j++)

理由:i=0 当第一趟冒泡排序排好之后 i++变成1 ,此时最后一个元素已经定好了最终位置,只需要剩下的前8个元素进行冒泡排序即可,下标最大为numsSize -1 -i

3.减少比较次数

这里为什么要再定义一个flag变量呢?

为了减少两两比较的次数,优化算法。

在每一趟冒泡排序开始之前 初始化flag = 1 用来假设此趟冒泡排序之前数组已经有序

为什么要这样做呢?随机的数组不一定都是无序的 有可能只是其中某几个元素需要交换

例如下面这个数组

int nums[] = { 1,2,3,4,6,5,7,8,9 };

这个数组其实只需要5和6交换位置就有序了

但如果没有flag变量的话 计算机就需要从头比较到尾 每两个元素都比较一下,看看是否要交换

重复性高。

flag具体实现:

if (nums[j] > nums[j + 1])
			{
				int tmp = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = tmp;
				flag = 0;
			}

在if语句中定义flag的值为0,一趟冒泡排序中,

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值