冒泡排序
来源:互联网 发布:淘宝客怎么做 编辑:程序博客网 时间:2024/06/16 17:07
------------------siwuxie095
冒泡排序法
它的工作原理如下:
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误
就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,
也就是说该数列已经排序完成
这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端
参考链接:
参考链接1,参考链接2,参考链接3
程序 1:冒泡排序法的实现
SortTestHelper.h:
#ifndef SORTTESTHELPER_H
#define SORTTESTHELPER_H
#include <iostream>
#include <string>
#include <ctime>
#include <cassert>
using namespace std;
//辅助排序测试
namespace SortTestHelper
{
//生成测试数据(测试用例),返回一个随机生成的数组:
//生成有n个元素的随机数组,每个元素的随机范围为[rangeL,rangeR]
int *generateRandomArray(int n,int rangeL, int rangeR)
{
//默认rangeL要小于等于rangeR
assert(rangeL <= rangeR);
int *arr =newint[n];
//对于数组中的每一个元素,将之随机成为rangeL和rangeR之间的随机数
//先设置随机种子:这里将当前的时间作为种子来进行随机数的设置
srand(time(NULL));
for (int i =0; i < n; i++)
{
//rand()函数+百分号+数的范围,即取中间的一个随机整数,再加上rangeL即可
arr[i] = rand() % (rangeR - rangeL +1) + rangeL;
}
return arr;
}
//生成一个近乎有序的数组
int *generateNearlyOrderedArray(int n,int swapTimes)
{
//先生成完全有序的数组
int *arr =newint[n];
for (int i =0; i < n; i++)
{
arr[i] = i;
}
//以当前时间为随机种子
srand(time(NULL));
//再随机挑选几对元素进行交换,就是一个近乎有序的数组了
for (int i =0; i < swapTimes; i++)
{
int posx = rand() % n;
int posy = rand() % n;
swap(arr[posx], arr[posy]);
}
return arr;
}
template<typename T>
void printArray(T arr[],int n)
{
for (int i =0; i < n; i++)
{
cout << arr[i] <<" ";
}
cout << endl;
}
//经过排序算法排序后,再次确认是否已经完全排序
template<typename T>
bool isSorted(T arr[],int n)
{
for (int i =0; i < n - 1; i++)
{
if (arr[i]>arr[i +1])
{
return false;
}
}
return true;
}
//衡量一个算法的性能如何,最简单的方式就是看这个算法在特定数据集上的执行时间
//(1)传入排序算法的名字,方便打印输出
//(2)传入排序算法本身,即函数指针
//(3)传入测试用例:数组和元素个数
template<typename T>
void testSort(string sortName,void(*sort)(T[],int), T arr[], int n)
{
//在排序前后分别调用clock()函数
//时间差就是该排序算法执行的时钟周期的个数
clock_t startTime = clock();
sort(arr, n);
clock_t endTime = clock();
assert(isSorted(arr, n));
//endTime减去 startTime转为double类型,除以 CLOCKS_PER_SEC,其中:
//
//CLOCKS_PER_SEC是标准库中定义的一个宏,表示每一秒钟所运行的时钟周期
//的个数,而(endTime-startTime)返回的是运行了几个时钟周期
//
//这样,最终的结果就是在这段时间中程序执行了多少秒
cout << sortName <<":" <<double(endTime - startTime) / CLOCKS_PER_SEC
<<"s" << endl;
}
//复制数组
int *copyIntArray(int a[],int n)
{
int *arr =newint[n];
//copy()函数在std中:
//第一个参数是原数组的头指针,
//第二个参数是原数组的尾指针,
//第三个参数是目的数组的头指针
//
//注意:copy()函数运行时会报错,需要在:
//项目->属性->配置属性->C/C++->预处理器->预处理器定义
//在其中添加:_SCL_SECURE_NO_WARNINGS
copy(a, a + n, arr);
return arr;
}
}
#endif
BubbleSort.h:
#ifndef BUBBLESORT_H
#define BUBBLESORT_H
//冒泡排序:从小到大进行排序
template<typename T>
void bubbleSort(T arr[],int n)
{
int i, j;
for (i =0; i < n -1; i++)
{
for (j =0; j < n -1 - i; j++)
{
if (arr[j] > arr[j +1])
{
swap(arr[j], arr[j +1]);
}
}
}
}
#endif
main.cpp:
#include"SortTestHelper.h"
#include"BubbleSort.h"
int main()
{
int n =10000;
int *arr = SortTestHelper::generateRandomArray(n,0, n);
SortTestHelper::testSort("Bubble Sort", bubbleSort, arr, n);
//SortTestHelper::printArray(arr, n);
delete[]arr;
system("pause");
return0;
}
//冒泡排序的性能整体没有插入排序好
运行一览:
程序 2:冒泡排序法的优化(在程序 1 的基础上,修改 BubbleSort.h 即可)
BubbleSort.h:
#ifndef BUBBLESORT_H
#define BUBBLESORT_H
//冒泡排序:从小到大进行排序
template<typename T>
void bubbleSort(T arr[],int n)
{
bool swapped;
do
{
swapped =false;
for (int i =1; i < n; i++)
{
if (arr[i -1] > arr[i])
{
swap(arr[i -1], arr[i]);
swapped =true;
}
}
//优化,每一趟Bubble Sort都将最大的元素放在了最后的位置
//所以下一次排序,最后的元素可以不再考虑
n--;
}while (swapped);
}
#endif
运行一览:
程序 3:冒泡排序法的再优化(在程序 2 的基础上,修改 BubbleSort.h 即可)
BubbleSort.h:
#ifndef BUBBLESORT_H
#define BUBBLESORT_H
//冒泡排序:从小到大进行排序
template<typename T>
void bubbleSort(T arr[],int n)
{
bool swapped;
//理论上,可以使用newn进行再优化,但实际优化效果较差
int newn;
do
{
swapped =false;
newn =0;
for (int i =1; i < n; i++)
{
if (arr[i -1] > arr[i])
{
swap(arr[i -1], arr[i]);
swapped =true;
//可以记录最后一次的交换位置,在此之后的元素在下一轮扫描中均不考虑
//实际优化效果较差,因为引入了newn这个新的变量
newn = n;
}
}
n = newn;
//优化,每一趟Bubble Sort都将最大的元素放在了最后的位置
//所以下一次排序,最后的元素可以不再考虑
//
//理论上,newn的优化是程序 2 中优化的复杂版本,应该更有效
//实测,使用简单优化(程序 2),时间性能更好
n--;
}while (swapped);
}
#endif
运行一览:
【made by siwuxie095】
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- 冒泡排序
- Unity3d笔记:炉石传说中的功能实现解析
- Gradle安装与配置
- CefSharp常见问题?
- Java 编程题目 第二题
- Python图表绘制:matplotlib绘图库
- 冒泡排序
- Android中Button的Selector自动生成
- 不是你无法入门自然语言处理(NLP),而是你没找到正确的打开
- Glide、Picasso、Fresco进阶
- 读取网盘文件下载到服务器
- CountDownTimerSupport
- outlook不能备份的解决
- c++ list, vector, map, set 区别与用法比较
- 如何开发一个抢单chrome插件