冒泡算法(C++模板实现)
冒泡排序
从整体上看,冒泡排序是一种稳定排序,即排序完成后,原本序列中的键值相等的元素相对位置不会发生改变。算法的时间复杂度是O(n2),空间复杂度为O(1),即这是一个“就地算法”。
简单的冒泡排序算法以及实现
冒泡算法的基本思想是先实现局部的有序性,再进一步实现整体的有序性。
从前向后依次检查每一对相邻元素,一旦发现逆序即交换二者的位置。对于长度为n的序列,共需做 n - 1次比较和不超过 n - 1次交换,这一过程称作一趟扫描交换。
举个例子,先来看看对于一个杂乱的序列{1, 3, 8, 2, 0, 5, 6, 4, 9, 7},如何排序成为一个升序呢?依据冒泡算法的基本思想,从前向后逐一对每一对相邻元素进行检查,若逆序则交换。
- 第1和2位,{1,3}顺序正确,看下一对
- 第2和3位,{3,8}顺序正确,看下一对
- 第3和4位,{8,2}顺序错误,进行交换,第3位变为2,第四位为8,即此时整体序列为{1, 3,
2, 8, 0, 5, 6, 4, 9, 7} - {8,0}又是错序,进行交换,{1, 3, 2,
0, 8, 5, 6, 4, 9, 7} - {1, 3, 2, 0,
5, 8, 6, 4, 9, 7} - {1, 3, 2, 0, 5,
6, 8, 4, 9, 7} - {1, 3, 2, 0, 5, 6,
4, 8, 9, 7} - 注意,此时{8,9}这一局部的序列是符合升序的,所以看下一对
- {9,7}是乱序的,进行交换。{1, 3, 2, 0, 5, 6, 4, 8,
7, 9}
以上,就完成了一趟扫描交换。每一次比较,局部内的较大值会交换到后面,小的值会交换到前面,就像气泡在水中浮向水面,所以称为冒泡算法。注意一点,每进行过一趟扫描为排序中的最大值已经“沉入”最后,所以下一趟比较时,需要比对的数对会较少一,即n减一。
代码实现如下(C++):
// 对一个数组a使用冒泡算法进行升序排序
template <typename T>
void bubbleSort_simple(T a[], int n) {
// n为数组的规模大小
int count = n;
// count用于辅助输出显示第几趟扫描比较
while (n--) {
for (int i = 0; i < n; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
cout << "这是第" << count - n <<"趟比较: ";
printArray(a); // 输出显示数组的函数
}
}
运行结果如下图:

冒泡算法改进
观察前面的结果,可以发现其实第4趟比较后就已经达成目标了,然而原来程序中依然要等while (n--)执行完,令n等于0才能结束,会浪费不少时间和系统资源。针对这一状况,可以设立一个标志位值。思想是这样的:当每次做一趟扫描,设最后发生过交换数值的位置为K,K的后面的位置的值已经是按序的了。下一趟排序就只用扫描到K位置之前的。若新的这一趟中的K值与上一轮相同,表明排序已经完成。
改进的冒泡算法代码实现如下:
template <typename T>
void bubbleSort_improved(T a[], int n) {
// n为数组的规模大小
int count = 0; // count用于记录第几趟扫描比较
int pos = n; // pos用于记录每一趟最后有发生交换的位置
int oldPos = 0; // 记录上一趟的最后有发生交换的位置,
// 与pos对比,若一样,说明已经排好序
while (n > 0 && n != oldPos) {
oldPos = n;
for (int i = 0; i < n; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
pos = i;
}
}
n = pos;
count++;
cout << "这是第" << count <<"趟比较后: ";
printArray(a);
}
}
运行结果如下:

双向冒泡算法(鸡尾酒算法)
传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,如果利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数大幅减少。
双向冒泡算法代码实现:
template <typename T>
void bubbleSort_bidirectional(T a[], int n) {
// n为数组的规模大小
cout << "双向冒泡排序实现。" << endl;
int count = 0;
int low = 0;
int high = n - 1;
while (low < high) {
for (int i = low; i < high; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
high--;
for (int j = high; j > low; j--) {
if (a[j] < a[j - 1]) {
T temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
low++;
count++;
cout << "第" << count <<"趟比较后: ";
printArray(a);
}
}
运行结果:

完整代码如下
#include <iostream>
using namespace std;
template <typename T>
void printArray(T a[]) {
int count = 10;
for (int i = 0; i < count; i++) {
cout << a[i] << " ";
}
cout << endl;
}
template <typename T>
void bubbleSort_simple(T a[], int n) {
// n为数组的规模大小
cout << "简单冒泡排序实现。" << endl;
int count = 0;
while (n--) {
for (int i = 0; i < n; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
count++;
cout << "第" << count <<"趟比较后: ";
printArray(a);
}
}
template <typename T>
void bubbleSort_improved(T a[], int n) {
// n为数组的规模大小
cout << "冒泡排序改进版实现。" << endl;
int count = 0; // count用于记录第几趟扫描比较
int pos = n; // pos用于记录每一趟最后有发生交换的位置
int oldPos = 0; // 记录上一趟的最后有发生交换的位置,
// 与pos对比,若一样,说明已经排好序
while (n > 0 && n != oldPos) {
oldPos = n;
for (int i = 0; i < n; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
pos = i;
}
}
n = pos;
count++;
cout << "第" << count <<"趟比较后: ";
printArray(a);
}
}
template <typename T>
void bubbleSort_bidirectional(T a[], int n) {
// n为数组的规模大小
cout << "双向冒泡排序实现。" << endl;
int count = 0;
int low = 0;
int high = n - 1;
while (low < high) {
for (int i = low; i < high; i++) {
if (a[i] > a[i + 1]) {
T temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
high--;
for (int j = high; j > low; j--) {
if (a[j] < a[j - 1]) {
T temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
low++;
count++;
cout << "第" << count <<"趟比较后: ";
printArray(a);
}
}
int main() {
int a[10] = {1, 3, 8, 2, 0, 5, 6, 4, 9, 7};
double b[10] = {4, 7.42, 8.309, 2.1, 6.34, 9.078, 3.098, 1.23, 5.27, 0.243};
int c[10] = {1, 3, 8, 2, 0, 5, 6, 4, 9, 7};
bubbleSort_simple(a, 10);
cout << endl;
bubbleSort_improved(b, 10);
cout << endl;
bubbleSort_bidirectional(c, 10);
cout << endl;
printArray(a);
printArray(b);
printArray(c);
return 0;
}
冒泡算法(C++模板实现)的更多相关文章
- 1014 C语言文法定义与C程序的推导过程 程序:冒泡算法C程序(语法树)
阅读并理解提供给大家的C语言文法文件. 参考该文件写出一个自己好理解版的现实版的完整版的C语言文法. 给出一段C程序,画出用上述文法产生这段C程序的完整语法树. 程序:冒泡算法C程序 点此文字查看原图 ...
- 冒泡算法C#
冒泡算法C# namespace数组排序 { classProgram { staticvoidMain(string[]args) { inttemp=; ,,,,,,,,}; #region该段与 ...
- Python函数练习:冒泡算法+快速排序(二分法)
冒泡算法: #-*- coding: UTF-8 -*-#冒泡排序 def func(lt):if type(lt).__name__ !='list' and type(lt).__name__ ! ...
- javascript之冒泡算法
今天看了js中数组的方法,其中sort()方法用于排序,就让我想到学C语言的时候有一个冒泡算法,就想用js写一个. <script> var arr=[1,30,20,40,21,31,1 ...
- php的冒泡算法
<?php /* 冒泡算法 * @para $arr 传人进去排序的数组 * @return $newArr 排序之后的数组 */ function maopao($arr){ ...
- python学习之路-6 冒泡算法、递归、反射、os/sys模块详解
算法 冒泡算法 # 冒泡算法就是将需要排序的元素看作是一个个"气泡",最小的"气泡"最先浮出水面,排在最前面.从小到大依次排列. # 代码如下: li = [9 ...
- Python冒泡算法和修改配置文件
先学习之前未完成的冒泡算法 li = [13,22,6,99,11] 从小到大 从第一个数字比较把大的往后移位 for m in range(4): num1 = li[m] num2 = li[m+ ...
- Python之collections序列迭代器下标式循环冒泡算法等
练习题 元素分类 有如下值集合[11,22,33,44,55,66,77,88,99]将所有大于66的数作为一个列表放在字典的key为k1的value小于等于66的为k2的value {'k1':[7 ...
- Python系列之文件操作、冒泡算法、装饰器、及递归
文件处理 python对文件进行读写操作的方法与具体步骤,包括打开文件.读取内容.写入文件.文件中的内容定位.及关闭文件释放资源等 open().file(),这个两函数提供了初始化输入\输出(I\O ...
随机推荐
- ImportError: No module named pysqlite2 --安装pysqlite
yum install sqlite-devel -y pip install pysqlite 每次使用yum安装额外的包之后都需要重新安装python,否则可能会有各种奇奇怪怪的问题出现 cd P ...
- 银联SDK
最近在开发一个app,需要调用银联的sdk控件,银联提供的demo可以正常运行,但是自己的程序却怎么都编译不通过,到底有哪些需要注意的呢?? 具体的有可能会出现哪些错误我就不列举了,我只是提下有哪些需 ...
- 【深度学习系列2】Mariana DNN多GPU数据并行框架
[深度学习系列2]Mariana DNN多GPU数据并行框架 本文是腾讯深度学习系列文章的第二篇,聚焦于腾讯深度学习平台Mariana中深度神经网络DNN的多GPU数据并行框架. 深度神经网络( ...
- responsive web design
http://d.alistapart.com/responsive-web-design/ex/ex-site-flexible.html http://alistapart.com/article ...
- 对 APM 用户的一次真实调查分析(上)
一.前言 国内的 APM 行业这两年刚刚起步,但是在国外却比较成熟了,并且由于这两年人力成本的快速提高,国内外涌现了几家非常不错的 APM 企业,例如,OneAPM,APPdynamic,Dynami ...
- Mybatis bug修正
http://1358440610-qq-com.iteye.com/blog/1827391
- ZOJ 3609 Modular Inverse
点我看题目 题意 : 这个题是求逆元的,怎么说呢,题目看着很别扭....就是给你a和m,让你求一个最小的x满足a-1≡x (mod m).或者ax≡1 (mod m).通俗点说呢,就是找一个最小的x, ...
- HDU2167+状态压缩DP
状态压缩dp 详见代码 /* 状态压缩dp dp[ i ][ j ]:第i行j状态的最大和 dp[i][j] = max( dp[i-1][k]+sum[i][j] ); 题意:给定一个N*N的方格, ...
- Hibernate 一对多自身双向关联关系 用于类别表的实现
分类:一对多自身双向关联关系 Java持久化类: package com.hyy.hibernate.one_to_many.domain; import java.util.HashSet; imp ...
- Java缓存--JCS
添加外部包: jcs-1.3.jar concurrent-10.3.jar cache.cff # optional region "myCache" specific conf ...