冒泡排序(C语言实现)

冒泡排序的基本思想:

冒泡排序(Bubble Sort):由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。

冒泡排序流程:

  • 比较相邻的元素。若前一个比后一个大,就交换它们两个(小数往前放,大数往后放)
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对
  • 完成一次冒泡排序
  • 针对所有的元素重复以上的步骤,除了最后一个
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

冒泡排序图解 :

首先,我们定义一个乱序排列的数组,需要将它升序排列

这里,我们定义了 一个降序排列的数组arr,这是一种最坏的情况

冒泡排序(C语言实现)_第1张图片

接下来我们开始第一趟冒泡排序,一趟冒泡排序可以使一个元素回归到正确位置

第一次比较

冒泡排序(C语言实现)_第2张图片

交换之后数组中的元素更新如下图,并进行下一次比较

第二次比较

冒泡排序(C语言实现)_第3张图片

同理,进行下一次比较

第三次比较

冒泡排序(C语言实现)_第4张图片

 第四次比较

冒泡排序(C语言实现)_第5张图片

第五次比较

冒泡排序(C语言实现)_第6张图片

第六次比较

冒泡排序(C语言实现)_第7张图片

第七次比较

冒泡排序(C语言实现)_第8张图片

第八次比较

冒泡排序(C语言实现)_第9张图片

第九次比较

交换之后,数组中元素更新为下图

冒泡排序(C语言实现)_第10张图片

此时,已经进行完了一趟冒泡排序,一个元素(实际上是最大的元素)已经回归到了正确位置,在这一趟冒泡排序中,我们进行了九次比较 

同理,在第二趟冒泡排序中,我们可以使次大元素回归到正确位置

冒泡排序(C语言实现)_第11张图片

冒泡排序(C语言实现)_第12张图片 冒泡排序(C语言实现)_第13张图片

冒泡排序(C语言实现)_第14张图片 

冒泡排序(C语言实现)_第15张图片 冒泡排序(C语言实现)_第16张图片

冒泡排序(C语言实现)_第17张图片 

为什么比较八次:因为第一趟冒泡排序之后,我们已经将最大数放到了最后的位置,次大数比较八次之后,没有必要再和最大数比较,此时的位置就是它的正确位置

八次比较并交换之后,数组更新为如下图: 

冒泡排序(C语言实现)_第18张图片

 同理,其他元素依次进行一趟冒泡排序,如下图

冒泡排序(C语言实现)_第19张图片

 第九趟冒泡排序之后,最小数没有必要再进行比较,已经自动被挤到了它的正确位置

综上所述:

当一个数组有十个元素时,总共需要进行9趟冒泡排序,即元素个数减一

总结:一个有sz个元素的数组,冒泡排序需要进行sz-1趟

对于第一趟冒泡排序,需要比较交换9次;

对于第二趟冒泡排序,需要比较交换8次;

同理,对于第三趟冒泡排序,需要比较交换8次 

... ...

对于第八趟冒泡排序,需要比较交换2次;

对于第九趟冒泡排序,只需要比较交换1次

每次比较交换的次数都是都是元素个数减一再依次减去0,1,2,... ... , sz-1

所以我们可以使用双层循环实现,外层循环一次进行一趟冒泡排序,内层循环实现比较交换

可以发现这些数字都是外层循环变量每次的取值

构造出双层循环的框架之后

我们可以发现一个小bug:当这个数组本身就是升序排列时,我们仍然需要不断地进入循环进行比较但是没有交换,这个操作是没有必要的,当一趟冒泡排序中没有交换操作时,就证明这个数组本身有序,没有必要进行下一趟冒泡排序,直接退出循环即可

因此我们可以定义一个标志变量flag,初始化为1,即假设这个数组有序

当我们有交换操作时,同时置falg为0,证明数组无序,需要进行下一趟冒泡排序

但是当我们内层循环结束时,判断flag仍然为1,即证明这一趟冒泡排序中没有交换操作,数组已经有序了,所以直接break退出循环

 使用冒泡排序法将整形乱序数组升序排列:

#define _CRT_SECURE_NO_WARNINGS
#include
void bubble_sort(int* arr, int sz)
{
	int flag = 1;//假设已经有序
	int i = 0;
	//总共sz个数,进行sz-1趟排序
	for (i = 0; i < sz-1; i++)
	{
		int j = 0;
		//让第i个数到正确位置,一趟冒泡排序
		for (j = 0; j  arr[j + 1])
			{
				flag = 0;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
			
		}
		//若程序运行至此flag的值为1,证明一趟冒泡排序进行时,发现该数组有序,跳出循环
		if (flag == 1)
		{
			break;
		}
	}
}
int main()
{
	int arr[] = { 10,9,8,7,6,5,4,3,2,1 };//定义一个乱序数组
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组长度
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

你可能感兴趣的:(实例,c语言,后端,算法)