【数据结构与算法】:快速排序和冒泡排序-三,冒泡排序

时间:2024-04-12 22:54:36

1.基本思想:

从序列的一端开始往另一端冒泡,依次比较相邻的两个数的大小。

设数组长度为N。

1.每轮比较相邻的前后两个数据,如果前面数据大于(或者小于)后面的数据,就将这两个个数据交换。

2.这样每轮对数组的第0个数据到N-1个数据进行一次遍历后,最大或者最小的一个数据就到数组第N-1个位置。

3.第一轮比较到下标为N-1的数据(最后一个),以后每次比较都-1。

2.图解冒泡排序:
以 [ 8,2,5,9,7 ] 这组数字来做示例:
从左往右依次冒泡,将小的往右移动(排降序)
第一轮冒泡:

在这里插入图片描述
首先比较第一个数和第二个数的大小,我们发现 2 比 8 要小,那么保持原位,不做改动。位置还是 8,2,5,9,7 。指针往右移动一格,接着比较:

在这里插入图片描述

比较第二个数和第三个数的大小,发现 2 比 5 要小,所以位置交换,交换后数组更新为:[ 8,5,2,9,7 ]。
指针再往右移动一格,继续比较:

在这里插入图片描述

比较第三个数和第四个数的大小,发现 2 比 9 要小,所以位置交换,交换后数组更新为:[ 8,5,9,2,7 ]。同样,指针再往右移动,继续比较:

在这里插入图片描述

比较第 4 个数和第 5 个数的大小,发现 2 比 7 要小,所以位置交换,交换后数组更新为:[ 8,5,9,7,2 ]。

下一步,指针再往右移动,发现已经到底了,则本轮冒泡结束,处于最右边的 2 就是已经排好序的数字。

通过这一轮不断的对比交换,数组中最小的数字移动到了最右边。

重复上述步骤,得到的最终结果是:

在这里插入图片描述
3.代码实现冒泡排序如下:


void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void BubbleSort(int* arr, int sz)
{
	for (int j = 0; j < sz; j++)
	{
		//一趟排序
		for (int i = 1; i < sz-j; i++)
		{
			if (arr[i - 1] < arr[i])
			{
				//前一个比后一个小,就交换
				Swap(&arr[i - 1], &arr[i]);
			}
		}
	}
}

4.冒泡排序的小优化:

假设我们要排降序,如果数组此时就是降序,那么在第一轮比较过后数据并没有发生交换,那就不要再进行多于的后续比较了,直接跳出循环即可。

void BubbleSort(int* arr, int sz)
{

	for (int j = 0; j < sz; j++)
	{
		int exchange = 0;//默认是有序的
		//一趟排序
		for (int i = 1; i < sz-j; i++)
		{
			if (arr[i - 1] > arr[i])
			{
				//前一个比后一个大,就交换
				Swap(&arr[i - 1], &arr[i]);
				
				//如果不是有序的就发生了交换,exchange=1
				exchange = 1; 
			}
		}
		//如果一趟比较过后发现是有序的,就直接跳出循环
		if (exchange == 0)
		{
			break;
		}
	}
}

5.时间复杂度和稳定性的分析

最好:就是顺序时,时间复杂度为O(N)
乱序时:时间复杂度为O(N*N)

所以冒泡排序的时间复杂度是O(N*N)。
冒泡排序算法是稳定的。