必威体育Betway必威体育官网
当前位置:首页 > IT技术

简单易懂排序算法(一)【冒泡排序】

时间:2019-06-28 07:44:16来源:IT技术作者:seo实验室小编阅读:82次「手机版」
 

冒泡排序算法

冒泡排序一种交换排序,基本思想是两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止

1.容易理解的代码:

void BubbleSort(vector<int>& vec)
{
	int n = vec.size();
	for (int i = 0; i < n - 1; ++i)
	{
		for (int j = i + 1; j < n; ++j)
		{
			if (vec[i] > vec[j]) 
				swap(vec[i], vec[j]);
		}
	}
}

在这里我们传入向量的引用,可以直接改变vectorvectorvector的值,后续也是如此应用

上述代码理解起来还是比较简单的,但效率非常低,可以以一个简单的例子来测试一下:

初始序列:9,1,5,8,3,7,6,2

在这里插入图片描述

可以看到在第二次排序之后3被换到了最后面,即在排好了1和2的位置后,对于其他关键字的排序并没有什么帮助,由此可以看出这个算法的效率非常低。

2.标准的冒泡排序

void BubbleSort(vector<int>& vec)
{
	int n = vec.size();
	for (int i = 0; i < n; ++i)
	{
		for (int j = n - 1; j >= i; --j) //注意j说从后往前循环
		{
			if (vec[j] > vec[j + 1]) 
				swap(vec[j], vec[j + 1]);
		}
	}
}

还是以上述例子来进行测试:

初始序列:9,1,5,8,3,7,4,6,2

在这里插入图片描述

可以看到每一次排序过后最小的值都到了指定的位置,同时我们与上一个算法比较一下,即在第二次排序之后,上一个算法中3到了最后面,而在这个算法中3、4都较之前的序列往前进了,这种差异在小序列可能并不是很明显,但当序列足够大时这种差异就会体现出来。

从结果可以看到,每一个较小的数字像气泡一样慢慢浮到了前面,因此也被称为冒泡排序

3.改进的冒泡排序

在给出的序列已基本有序的情况下,例:2,1,3,4,5,6,7,8,9

简单测试一下:

在这里插入图片描述

可以看到,在序列基本有序的情况下,在第一次排序后就已经完全有序,但此时算法仍在不断的进行循环判断,这种无意义的循环判断明显的降低了效率,因此,为了减少这种无意义的判断,我们可以将算法作如下改进:

void BubbleSort(vector<int>& vec)
{
	int n = vec.size();
	bool flag = 1;
	for (int i = 0; i < n && flag; ++i)
	{
		flag = 0;
		for (int j = n - 1; j >= i; --j)
		{
			if (vec[j] > vec[j + 1]) {
				swap(vec[j], vec[j + 1]);
				flag = 1;  //有交换则置为1
			}
		}
	}
}

结果如下:

在这里插入图片描述

可以看到明显的减少了无意义的循环判断,再来简单分析一下代码的改动:

代码改动的关键在于i变量的for循环中,增加了对flag是否为1的判断,经过这样的判断,就能知道代码是否有序,因为如果有序的话则flagflagflag为falsefalsefalse直接跳出循环.

冒泡排序时间复杂度分析

简单分析一下时间复杂度。

  • 在最好的情况下,也就是要排序的表本身是有序的,根据我们改进的代码,可以得出经过n1n-1n−1次的比较,没有数据交换,时间复杂度为O(n)
  • 在最坏的情况下,即待排序表是逆序的情况下,此时需要比较

i=1n(i1)\sum\limits_{i=1}^n (i-1)i=1∑n​(i−1) = 1 + 2 + 3 + … + (n - 1) = n(n1)2\frac{n(n-1)}{2}2n(n−1)​次

并作等数量级的记录移动。

  • 因此,总的时间复杂度为O(n^2)
  • 一种稳定的排序算法

测试代码:

#include <iostream>
#include <vector>
using namespace std;

void BubbleSort(vector<int>& vec);
void PrintStep(vector<int> vec, int n, int i);
void PrintResult(vector<int> vec, int n);

void BubbleSort(vector<int>& vec)
{
	cout << "--------------冒泡排序--------------" << endl;
	int n = vec.size();
	bool flag = 1;
	for (int i = 0; i < n && flag ; ++i)
	{
		flag = 0;
		for (int j = n - 2; j >= i; --j)
		{
			if (vec[j] > vec[j + 1]) {
				swap(vec[j], vec[j + 1]);
				flag = 1;
			}
		}
		PrintStep(vec, n, i);
	}
	cout << "最终排序结果为:";
	PrintResult(vec, n);
}

void PrintStep(vector<int> vec, int n, int i)
{
	cout << "第" << i + 1 << "次排序结果: ";
	for (int j = 0; j < n; ++j)
		cout << vec[j] << ' ';
	cout << endl;
}

void PrintResult(vector<int> vec, int n)
{
	for (int j = 0; j < n; ++j)
		cout << vec[j] << ' ';
	cout << endl;
}
int main(int argc, char **argv)
{
	int a[] = {2,1,3,4,5,6,7,8,9};
	vector<int > vec(a, a+9);
	BubbleSort(vec);
	return 0;
}

相关阅读

走进开发,5分钟熟悉3种经典排序算法

若干年前pony在腾讯产品暨技术峰会上就说过:“我们希望的产品经理是从技术晋升而来的。”技术是实施手段,产品最终还是要靠技术来实

常用排序算法总结(1)-- 比较排序

我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。排序算法大体可分为两种:一种是比较排序,时间复杂度O(

揭秘我烧网热文排序算法—SmartHot

就像Google不会公布其搜索排名算法一样,大多数公司都不会对外公布涉及排名的算法。因为这个算法一旦公布,总会有人去做SPAM。同理,我

分享到:

栏目导航

推荐阅读

热门阅读