排序算法——冒泡排序

1,094 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

冒泡排序:

“冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。”
冒泡排序是选择排序的一种,该排序的限制条件是——相邻比较,若满足某种条件则进行交换,直到无法在进行交换时,排序结束。

PS: 百度上有很多的动图演示,这里就不进行演示了,接下来将会讲述两种代码思路

传统代码思路:

1.进行n-1趟循环,即进行n-1次冒泡
2.每次冒泡需要比较n-i-1次比较,为什么呢,这是因为每次冒泡会把最大的数不断地向上冒泡 3.所以每次比较的次数是n-i-1次

传统代码如下:

#include<iostream>
using namespace std;
//冒泡排序函数
void BubbleSort(int a[], int n) {
	for (int i = 0; i < n - 1; i++) {//一共要比较i-1躺
		for (int j = 0; j < n - i - 1; j++) {//每一次比较n-1-i次
			if (a[j] > a[j + 1]) {
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}
//display函数
void display(int a[], int n) {
	for (int i = 0; i < n; i++)
		cout << a[i] << "  ";
}
int main()
{
	int n;
	cin >> n;
	int* a = new int[n];
	for (int i = 0; i < n; i++)
		cin >> a[i];
	BubbleSort(a, n);
	display(a, n);
}

PS: 相信很多人的冒泡排序都是这样,这是顺着冒泡排序的思路来的,假如遇到了下图这种情况的话……

image.png 你会发现,只需要一次冒泡即可实现排序,但是传统的冒泡排序仍然需要比较这么多次,那么有没有一种方法可以使其跳过这样的情况呢,答案当然是有的~
在这之前,我先介绍一种交换函数

交换函数

void Swap(int& x, int& y) {
	x = x - y;
	y = x + y;
	x = y - x;
}

这是一种不需要中间变量的函数,里面的交换规则来源于数学,这里就不细述了,读者细细品味~

冒泡排序新思路:

1.找一个中间遍历exchange,和一个二层的循环变量bound
2.每次二层循环(比较)需要变更exchange的值
3.正如前面说到的,如果有一段已经是正序的,exchange的值不变,这样的话可以缩减很多的步骤,直接到正序的前一个开始

冒泡排序新代码:

#include<iostream>
using namespace std;

void Swap(int& x, int& y) {
	x = x - y;
	y = x + y;
	x = y - x;
}

void BubbleSort(int a[], int n) {
	int exchange = n - 1;
	while (exchange) {
		int bound = exchange;//二层循环结束条件
		exchange = 0;//若没有以下比较,exchange=0,循环结束
		for (int j = 0; j < bound; j++) {
			if (a[j] > a[j + 1]) {
				Swap(a[j], a[j + 1]);
				exchange = j;
			}
		}
	}
}

int main()
{
	int n;
	cin >> n;
	int* a = new int[n];
	for (int i = 0; i < n; i++)
		cin >> a[i];
	BubbleSort(a, n);
	for (int i = 0; i < n; i++)
		cout << a[i] << " ";
}

PS: 以上就是冒泡排序算法的细节了~