对一组随机生成数进行几种常用排序算法的分析设计和实现之一 ——冒泡排序
基本算法的掌握和理解对程序员的发展有至关重要的作用。因此,在科研之余,将各种基本算法重新整理分析和实现以加深对基本算法的理解,打好基本功,也希望这一系列的小文章能为大家加深算法理解和编程方面的学习有所帮助,不足及错去之处也希望大家批评指正。
这些算法的代码我都已经在VS2010下,又C++语言编译实现,并有详细的注释,以方便大家阅读。
好了,进入主题,第一篇对一组随机生成数进行几种常用排序算法的分析设计和实现之一 ——冒泡排序。
首先进行算法分析,
一、是伪代码:
void BubbleSort(SeqList R)
{ //iRan(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序
int i,j,NUM;//NUM采用宏定义,方便数目的控制
//用冒泡排序法进行降序排列
for(j = 0; j < NUM - 1; j++) //外循环,控制内循环趟数
for(i = 0; i < NUM - 1-j; i++)//内循环,注意控制每次循环的边界,尤其结束边界
{
if(iRan[i] < iRan[i+1]) //如果前面的数小于后面的数进行交换
sw = iRan[i+1];
iRan[i+1] = iRan[i];
iRan[i] = sw;
}
二、复杂度分析
(1)算法的最好时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:
Cmin=n-1
Mmin=0。
冒泡排序最好的时间复杂度为O(n)。
(2)算法的最坏时间复杂度
若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
Cmax=n(n-1)/2=O(n2)
Mmax=3n(n-1)/2=O(n2)
冒泡排序的最坏时间复杂度为O(n2)。
(3)算法的平均时间复杂度为O(n2)
虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。
(4)算法稳定性
冒泡排序是就地排序,且它是稳定的。
三、C++源码
//随机生成的整数进行冒泡的降序排列。
#include <iostream>
#include <stdlib.h>
#define NUM 10000
int main()
{
int iRan[NUM];
int i,j,sw;
char st;
for(i = 0;i < NUM;i++)
{
iRan[i] = rand();//随机生成NUM个整数存放在数组iRan里
}
for(i = 0; i < NUM; i++)
std::cout<< iRan[i] << std::endl;
std::cout <<"Please input the instruction y or n " //如果你认为这组数据是你想要的,请输入一,
<< std::endl;
//如果数据不是你想要的如数n重新运行程序重新生成
std::cin >> st;
if (st == 'y')
{
for(j = 0; j < NUM - 1; j++)//用冒泡排序法进行降序排列
for(i = 0; i < NUM - 1-j; i++)
{
if(iRan[i] < iRan[i+1])
sw = iRan[i+1];
iRan[i+1] = iRan[i];
iRan[i] = sw;
}
for(i = 0; i < NUM; i++)
std::cout<<iRan[i]<<" ";
}
return 0;
}
100个随机数的运行结果:
四、利用 Time下的进程时间统计函数统计本次排序所耗费的时间,以便和以后的算法从相同因素下所耗费的时间这个层面上进行对比,已得到一个更为直观的认识。
本次程序执行的结果如下
267毫秒
在接下来的一段时间里,博主还会以同样的思路学习和分析其他排序算法。谢谢大家花费宝贵的时间和我交流我的学习体会。