冒泡排序

来源:互联网 发布:淘宝客怎么做 编辑:程序博客网 时间: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];

  

//对于数组中的每一个元素,将之随机成为rangeLrangeR之间的随机数

//先设置随机种子:这里将当前的时间作为种子来进行随机数的设置

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】

原创粉丝点击