一 问题描述
对一个较大规模的数组进行排序,分别使用冒泡,快速,和堆排序,比较这三种方法的效率.
二 算法分析与设计
三种算法要比较哪一个效率更高,必须使用相同的数组进行排序,而且数组的元素个数要相当大,这样才能够看处它们执行效率的差别。要输入一个很大的数组显然不符合现实,因为工程太庞大了,所以我们用随机产生函数:rang()来产生所要的数组,虽然每次产生的数组都不一样,但是随机性更能体现出一个算法执行的好和坏。我们并不是就执行一次,而是通过多次的执行得出结论。
数组产生了以后,接下来的事情就是用每一种排序方法对产生的数组进行排序,同时记录下排序所需要的时间,我们通过所花时间的多少来比较哪个算法的效率高。记录时间我们用:
t=clock()这个函数,开始排序的时间:t1=clock();和结束排序后的时间:t2=clock().两者相减得到:t=t2-t1,t就是所花的时间,t/CLOCKS_PER_SEC就把所花的时间转化为秒数。
这样,我们只要再程序运行的时候输入数组的大小,就可以通过不同的排序得出不同的排序所花的时间,从而得出比较的结果。
三 时间复杂度分析
冒泡排序的时间复杂度为: T(n) = O(n^2)
快速排序的时间复杂度为: T(n) = O(n*log n) (前面的报告中已经有分析说明)
堆 排序的时间复杂度为 : T(n) = O(n*log n) ( 在最坏的情况下)
堆排序的运行时间主要是耗费在建立初始堆和调整建立新堆的反复筛选上面,在建立初始堆的时候,需要的时间是0(n);因为在建初始堆的时候,调用Heapify() n/2次,有Heapify()所需要的时间可知道,当i在n/2的到n/4+1的范围内时,每次调用耗费时间为C,C为一常数,当i在n/4到n/8+1的范围内时,耗费的时间为2C,………。所以
C(n/4+2*n/8+3*n/16+……..)=O(n)
在调整堆的时候,调用Heapify共n-1次,每次调用所需要的时间为O(n)的时间,所以整个算法在最坏的情况下只需要:T(n) = O(n*log n) 的时间。
四 运行结果和分析
1)当数组的规模都为10000个元素的时候:
冒泡排序所需的时间是:0.625秒;快速排序和堆排序基本上不需要时间(因为规模比较小所以看不出来)。
2)当数组的规模都为100000个元素的时候:
冒泡排序所需要的时间为:69.875秒;
快速排序所需要的时间为:0.047 秒;
堆 排序所需要的时间为:0.031 秒;
从上面的比较不难看出堆排序要比快速好,快速又要比冒泡排序好。但这时候堆排序和快速排序所花的时间相差不时很多。
3)当数组规模为1000000个元素的时候:
这主要是比较快速排序和堆排序之间的差距,因为当规模这么大时,冒泡排序要花太多时间所以就没有进行比较测试。从结果中可以看到,当数组规模很大的时候,堆排序的优势就彻底的体现出来了,比快速排序要块很多。所以证明了一点,当数组元素很大的时候,用堆排序时最优的。
--------------------------------------------------------------------------------
附 源程序
// 主程序 (.cpp文件)
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
#include "BobbleSort.h"
#include "QuickSort.h"
#include "HeapSort.h"
int main()
{
int N;
int *a;
time_t start ,end;
double usetime;
int i,j;
i=1;
while(i<=3)
{
if(i==1)
printf("--------------------冒 泡 排 序--------------------\n");
else if(i==2)
printf("--------------------快 速 排 序--------------------\n");
else if(i==3)
printf("-------------------- 堆 排 序 --------------------\n");
printf("输入数组元素N的值: ");
scanf("%d",&N);
if(i==3)
a=(int *)malloc((N+1)*sizeof(int));
else
a=(int *)malloc(N*sizeof(int));
if(!a)exit(1);
srand(time(NULL));
if(i==3)
for(j=1;j<=N;j++)
a[j]=rand()%1000;
else
for(j=0;j<N;j++)
a[j]=rand()%1000;
start=clock();
if(i==1)
BobbleSort(a,N);
else if(i==2)
QuickSort(a,0,N-1);
else if(i==3)
HeapSort(a,N);
end=clock();
usetime=(end-start)*1.0/CLOCKS_PER_SEC;
printf("该排序所花的时间为:");
printf("%lf 秒\n",usetime);
free(a);
i++;
}
getch();
return 0;
}
//********************************* BobbleSort.h文件
void BobbleSort(int a[],int N) //冒泡排序的算法
{
int k,flag,m,j;
flag=1; //设置一个标志位用来表示在每一轮的比较中是否有元素交换.
m=N-1;
while(flag>0)
{
flag=0;
k=m;
for(j=0;j<k;j++)
if(a[j]>a[j+1])
{
int t;
t=a[j];a[j]=a[j+1];a[j+1]=t;
flag=1;
m=j;
}
}
}
//************************************* QuickSort.h文件
int Partion(int a[],int low,int high) //找出分割位置
{
int key;
key=a[low];
while(low<high)
{
while(low<high&&a[high]>=key)high--;
a[low]=a[high];
while(low<high&&a[low]<=key)low++;
a[high]=a[low];
}
a[low]=key;
return low;
}
void QuickSort(int a[],int low,int high)
{
int po;
if(low<high)
{
po=Partion(a,low,high);
QuickSort(a,low,po-1); //递归调用
QuickSort(a,po+1,high);
}
else return ;
}
//***************************************** HeapSort.h 文件
void swap(int &a,int &b)
{
a=a+b;
b=a-b;
a=a-b;
}
void Heapify(int a[],int k,int m) //整理堆
{
int k1=2*k;
int k2=2*k+1;
if(k2<=m)
{
if((a[k1]>a[k2]&&a[k2]>a[k])||(a[k1]>a[k]&&a[k2]<a[k]))
{
swap(a[k1],a[k]);
Heapify(a,k1,m);
}
else if((a[k1]<a[k2]&&a[k1]>a[k])||(a[k2]>a[k]&&a[k]>a[k1]))
{
swap(a[k2],a[k]);
Heapify(a,k2,m);
}
}
else if(k1<=m)
{
if(a[k1]>a[k])
{
swap(a[k1],a[k]);
Heapify(a,k1,m);
}
}
else return ;
}
void HeapSort(int a[],int m)
{
int i;
for(i=m/2;i>=1;i--)
Heapify(a,i,m);
for(i=m;i>1;i--)
{
swap(a[i],a[1]);
Heapify(a,1,i-1);
}
}
分享到:
相关推荐
本文将深入探讨四种在C++中实现的常见排序算法:插入排序、冒泡排序、堆排序和快速排序。这些算法各有特点,适用于不同的场景,理解并掌握它们对于提升编程能力至关重要。 1. **插入排序**: 插入排序是一种简单的...
直接插入排序、冒泡排序、快速排序、直接选择排序、堆排序和二路归并排序是计算机科学中经典的排序算法,它们在数据处理和算法学习中占有重要地位。这些排序算法各有特点,适用场景不同,下面将逐一详细介绍,并结合...
本文将深入探讨Java编程语言中实现的七种主要排序算法:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序以及归并排序。每种算法都有其独特性,适用于不同的场景和数据特性。 1. **直接插入排序**:...
直接插入排序 选择排序 堆排序 归并排序 快速排序 冒泡排序等七种排序方法
本篇文章将详细讲解四种经典的排序算法:快速排序、冒泡排序、选择排序和堆排序。 **快速排序**,由C.A.R. Hoare在1960年提出,是一种效率较高的分治算法。它的基本思想是选取一个“基准”元素,通过一趟排序将待...
数据结构(c语言版)严蔚敏 吴伟民编著 中直接插入排序、折半排序、shell排序、冒泡排序、快速排序、选择排序、堆排序的实现、归并排序,使用c语言实现
本话题主要探讨六种内部排序算法:直接插入排序、希尔排序、冒泡排序、快速排序、选择排序以及堆排序。这六种排序算法各有优劣,适用于不同的场景,接下来我们将逐一进行详细阐述。 1. **直接插入排序**: 直接...
本资源提供了七大经典排序算法的实现程序,包括快速排序、冒泡排序、选择排序、归并排序、插入排序、希尔排序和堆排序。下面将逐一详细介绍这些排序算法及其原理。 1. 快速排序:由C.A.R. Hoare提出,是一种采用...
本主题将详细探讨希尔排序、冒泡排序、堆排序等经典的排序算法,这些都是数据结构与算法学习中的核心内容,尤其对于北邮数据结构课程来说,理解并掌握这些排序方法至关重要。 1. **插入排序**: 插入排序是一种...
以下是关于"冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序"这七种常见排序算法的源码实现及相关知识点的详细解释: 1. **冒泡排序**:冒泡排序是一种简单的排序算法,它重复地遍历待排序的...
堆排序和快速排序在中大规模数据上表现良好,但快速排序的不稳定性和堆排序的空间复杂度是需要注意的问题;归并排序和希尔排序在稳定性上有优势,而桶排序则对输入数据分布有特定要求。在实际应用中,根据数据特性...
本资源包"选择排序 冒泡排序 插入排序 快速排序 堆排序.zip"聚焦于五种经典的排序算法,包括选择排序、冒泡排序、插入排序、快速排序以及堆排序。这些算法的实现语言是Objective-C,这是一种强大的面向对象的编程...
排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序.mht
快速排序和冒泡排序是两种常见的排序算法,它们在计算机科学中扮演着重要的角色,特别是在数据处理和优化程序性能方面。本篇文章将深入探讨这两种排序算法的原理、效率以及它们在C#编程语言中的实现。 首先,让我们...
- 冒泡排序通过重复遍历待排序的数列,比较相邻元素的大小,然后根据比较结果交换它们的位置,直到没有任何一对数字需要比较为止。 - 在C#中,使用嵌套循环实现,外层循环控制遍历次数,内层循环用于相邻元素的...
冒泡排序代码,使用 Python 进行插入排序、选择排序、冒泡排序、合并排序、快速排序、堆排序的代码。 插入排序是一种简单的排序算法,通过构建有序序列,将未排序的元素逐一插入到已排序的部分。该算法适用于小规模...
排序算法汇总P: 冒泡排序快速排序直接选择排序插入排序希尔排序 堆排序........
本资源包含了几种常见的排序算法,包括堆排序、选择排序、冒泡排序、归并排序和插入排序。这些排序算法各有特点,适用于不同的场景,并且在理解它们的工作原理后,能够帮助初学者更好地掌握编程基础。 1. **堆排序*...
常见的几种排序方式,包括选择排序,冒泡排序,快速排序,希尔排序,堆排序,插入排序。vs2008实现,对话框方式,主要实现字符串的由小到大排序。点击“几种排序方法.vcproj“运行。字符集使用多字节集,不能用...