Echo_sun

导航

算法初步——冒泡排序

通过观察桶排序,我们很容易发现一个致命问题:当我们需要排序的最大数为1000000时,我们需要一个大小为1000001的数组,这就会导致数组占用的内存很大,浪费很多空间。于是,我们有了一种新的排序方法——冒泡排序。

冒泡排序的基本思想是:每次比较相邻的两个元素,如果他们的顺序错误,则把他们的位置进行调换。

例如将3 10 6 27 82 17 22进行从大到小排序,我们的目标就是将较小的数字放到后面。所以比较第一位和第二位数字的大小,我们发现3<10,所以要将3和10进行调换,调换后变成10 3 6 27 82 17 22;紧接着将第二个数和第三个数进行比较发现3<6,我们依旧将3和6进行调换,变成10 6 3 27 82 17 22,以此类推,到此次循环结束时我们成功将这串数字变成了10 6 27 82 17 22 3,这样我们就确定了最后一位数字为3,在进行下一次循环时我们就需要再遍历到最后一位的3了;随后进行第二次遍历,遍历规则同上。每次遍历我们将确定一个相对小的位置,当我们确定到最后一个数字时,循环结束,我们就得到了排序后的数组。

#include<iostream>
using namespace std;
 
int main()
{
	int a[100], t, n;//n表示你需要排序的数字的个数
	cin >> n;
	for (int i = 0; i < n; i++)//我们遍历进行输入
	{
		cin >> a[i];
	}
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - i; j++)//此处仅需要遍历到n-i,可以思考一下为什么
		{
			if (a[j] < a[j + 1])
			{
				//交换过程,不必多说
				t = a[j];
				a[j] = a[j + 1];
				a[j + 1] = t;
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	return 0;
}

  利用冒泡排序我们就可以解决桶排序遗留下来的一个问题——不能对结构体数组进行排序。

#include<iostream>
using namespace std;
 
typedef struct Student//我们创建了一个结构体数组,用来存放一个学生的姓名和成绩
{
	char name[21];
	int score;
};
 
int main()
{
	Student stu[100], t;
	int n;
	cin >> n;//输入学生人数
	for (int i = 0; i < n; i++)
	{
		printf("请输入第%d个学生的姓名:", i + 1);
		cin >> stu[i].name;
		printf("请输入第%d个学生的成绩:", i + 1);
		cin >> stu[i].score;
		cout << endl;
	}
	//我们按成绩从高到低进行排序
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - i; j++)
		{
			if (stu[j].score < stu[j + 1].score)
			{
				t = stu[j];
				stu[j] = stu[j + 1];
				stu[j + 1] = t;
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		cout << stu[i].name << " " << stu[i].score << endl;
	}
	cout << endl;
	return 0;
}

  

这样我们就完成了一个学生管理系统中的一个重要函数:对学生成绩进行排序。

冒泡排序的核心部分是双重嵌套循环。我们很容易可以看出,冒泡排序的时间复杂度为O(N^2),这是一个非常高的时间复杂度。你以为我们的排序到此就结束了吗?不可能!在下一节我们将会介绍另一种常用的排序算法——快速排序。

posted on 2022-04-14 23:37  Echo_sun  阅读(49)  评论(0编辑  收藏  举报