C++起泡排序,直接排序,简单选择排序,快速排序,希尔排序,堆排序排序速度对比(包括伪随机数组生成)
下面是伪随机数组生成代码,注意预处理命令,在本文最下面的完整代码展示里面有体现 ,另外下面我设置的上限是5万,因为当数组长度为3万时所有排序执行时间都大于0.000秒,可大致看出各个排序的速度差距代码片
.
int randomnum[50000];//可以自己修改
int a[50000];//可以自己修改
srand(time(0));//设置种子,每回种下的种子不一样,得到的随机数不一样
int size;
cout<<"输入生成伪随机数的数目:"<<endl;
cin>>size;
for(int i=0;i<size;i++)
{
a[i]=rand()%size;
int j=i;
while(j--)
{
if(a[i]==a[j])//与之前的随机数比较,重复就再生成随机数,直到与之前不同
{
a[i]=rand()%size;
j=i;
}
}
randomnum[i]=a[i];//把生成的随机数存储到数组中
}
下面是起泡排序代码 代码片
.
void bubblesort(int a[],int size)//起泡排序
{
for(int j=1;j<size;j++)
{
for(int i=0;i<size-j;i++)
{
if(a[i]>a[i+1])
{
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
/*用来验证排序是否可行的输出
cout<<"起泡排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是直接排序代码 代码片
.
void directsort(int a[],int size)//直接排序
{
for(int i=1;i<size;i++)
{
if(a[i]<a[i-1])
{
for(int j=i;j>0;j--)
{
if(a[j]<a[j-1])
{
int t=a[j];
a[j]=a[j-1];
a[j-1]=t;
}
else
break;
}
}
}
/*用来验证排序是否可行的输出
cout<<"直接排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是简单选择排序代码 代码片
.
void selectsort(int a[],int size)//简单选择排序
{
for(int i=0;i<=size;++i)
{
int k=i;
for(int j=i+1;j<size;++j)
{
if(a[j]<a[k])
k=j;
}
if(k!=i)
{
int t=a[k];
a[k]=a[i];
a[i]=t;
}
}
/*用来验证排序是否可行的输出
cout<<"简单选择排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是快速排序代码 代码片
.
void quisort(int left,int right,int a[])//快速排序
{
if(left>=right)//这两步不可缺,不然你可以自己试一下缺了会发生什么事
return;
int base=a[left];//取最左边作为基准数,实际上取哪个作为基准数都行
int i=left;
int j=right;
while(i<j)
{
while(a[j]>=base&&i<j)//j从右边先开始找小于基准数的数
j--;
while(a[i]<=base&&i<j)//i从左边开始找大于基准数的数
i++;
if(i<j)//i,j都找到后交换数值
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=base;//交换i,j相遇位置数值和基准数
quisort(left,i-1,a);//在基准数左边重复上述过程,即递归左边
quisort(i+1,right,a);//在基准数右边重复上述过程,即递归右边
}
void quicksort(int a[],int size)//实际上一会在主函数中要调用的是这个函数
{
quisort(0,size-1,a);
/*用来验证排序是否可行的输出
cout<<"快速择排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是希尔排序代码 代码片
.
void shellsort(int a[],int size)//希尔排序
{
int h=1;
while(h<size/3)
h=3*h+1;
while(h>=1)
{
for(int i=h;i<size;++i)
{
for(int j=i;j>=h&&a[j]<a[j-h];j-=h)
{
int t=a[j];
a[j]=a[j-h];
a[j-h]=t;
}
}
h=h/3;
}
/*用来验证排序是否可行的输出
cout<<"希尔排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是堆排序代码 代码片
.
void exchange(int a[],int i,int j)//堆排序的交换函数
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
void heapify(int a[],int i ,int size)//堆排序的堆化函数
{
int left=2*i+1;//因为堆顶上面还有一个树根,所以2i和2i+1要都+1
int right=2*i+2;
int max=i;//当前父节点为最大
if(left<size&&a[left]>a[max])
max=left;//如果有左节点,且左节点值更大,则交换
if(right<size&&a[right]>a[max])
max=right;//如果有右节点,且右节点值更大,则交换
if(max!=i)
{
exchange(a,i,max);//最大值不是当前节点,则交换
heapify(a,max,size);//交换后子节点值已经变了,需要再次堆化调整
}
}
void heapsort(int a[],int size)//堆排序
{
//构建大顶堆
for(int i=size/2-1;i>=0;i--)
{
heapify(a,i,size);
}
//交换堆顶元素和尾部元素
for(int j=size-1;j>0;j--)
{
exchange(a,0,j);
size--;
heapify(a,0,size);
}
/*用来验证排序是否可行的输出
cout<<"堆排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
下面是菜单设置代码,注意使用clock函数的预处理命令,在本文最下面的完整代码展示里面有体现 代码片
.
int p=1;
while (p)//p不是false,所以会一直循环下去,这样就可以在执行完菜单中的某个选项之后,返回最初菜单
{
int a;
cout<<"--------菜单--------"<<endl;
cout<<"1.输出伪随机数"<<endl;
cout<<"2.输出各个排序耗时"<<endl;
cout<<"3.退出菜单"<<endl;
cout<<"--------------------"<<endl;
cout<<endl;
cout<<"请输入选项序号:";
cin>>a;
switch(a)
{
case 1:
cout<<endl;
if(a==1)//输出伪随机数
{
for(int j=0;j<size;j++)
cout<<randomnum[j]<<' ';
cout<<endl;
}
cout<<endl;
break;
case 2:
cout<<endl;
clock_t start1,end1,start2,end2,start3,end3,start4,end4,start5,end5,start6,end6;
double totaltime1,totaltime2,totaltime3,totaltime4,totaltime5,totaltime6;
start4=clock();
quicksort(randomnum,size);
end4=clock();
totaltime4=(double)(end4-start4)/CLOCKS_PER_SEC;
cout<<"快速排序耗时 "<<totaltime4<<" 秒"<<endl;
start5=clock();
shellsort(randomnum,size);
end5=clock();
totaltime5=(double)(end5-start5)/CLOCKS_PER_SEC;
cout<<"希尔排序耗时 "<<totaltime5<<" 秒"<<endl;
start2=clock();
directsort(randomnum,size);
end2=clock();
totaltime2=(double)(end2-start2)/CLOCKS_PER_SEC;
cout<<"直接排序耗时 "<<totaltime2<<" 秒"<<endl;
start1=clock();
bubblesort(randomnum,size);
end1=clock();
totaltime1=(double)(end1-start1)/CLOCKS_PER_SEC;
cout<<"起泡排序耗时 "<<totaltime1<<" 秒"<<endl;
start3=clock();
selectsort(randomnum,size);
end3=clock();
totaltime3=(double)(end3-start3)/CLOCKS_PER_SEC;
cout<<"简单选择排序耗时 "<<totaltime3<<" 秒"<<endl;
start6=clock();
heapsort(randomnum,size);
end6=clock();
totaltime6=(double)(end6-start6)/CLOCKS_PER_SEC;
cout<<"堆排序耗时 "<<totaltime6<<" 秒"<<endl;
cout<<endl;
break;
case 3:
p=false;
break;
default:
cout<<"没有此选项!"<<endl;
break;
}
}
cout<<endl;
cout<<"退出菜单成功!"<<endl;
下面是整个程序的完整代码 代码片
.
#include<iostream>
#include<string>
#include<stdlib.h>
#include<time.h>
using namespace std;
void bubblesort(int a[],int size)//起泡排序
{
for(int j=1;j<size;j++)
{
for(int i=0;i<size-j;i++)
{
if(a[i]>a[i+1])
{
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
/*用来验证排序是否可行的输出
cout<<"起泡排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
void directsort(int a[],int size)//直接排序
{
for(int i=1;i<size;i++)
{
if(a[i]<a[i-1])
{
for(int j=i;j>0;j--)
{
if(a[j]<a[j-1])
{
int t=a[j];
a[j]=a[j-1];
a[j-1]=t;
}
else
break;
}
}
}
/*用来验证排序是否可行的输出
cout<<"直接排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
void selectsort(int a[],int size)//简单选择排序
{
for(int i=0;i<=size;++i)
{
int k=i;
for(int j=i+1;j<size;++j)
{
if(a[j]<a[k])
k=j;
}
if(k!=i)
{
int t=a[k];
a[k]=a[i];
a[i]=t;
}
}
/*用来验证排序是否可行的输出
cout<<"简单选择排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
void quisort(int left,int right,int a[])//快速排序
{
if(left>=right)//这两步不可缺,不然你可以自己试一下缺了会发生什么事
return;
int base=a[left];//取最左边作为基准数,实际上取哪个作为基准数都行
int i=left;
int j=right;
while(i<j)
{
while(a[j]>=base&&i<j)//j从右边先开始找小于基准数的数
j--;
while(a[i]<=base&&i<j)//i从左边开始找大于基准数的数
i++;
if(i<j)//i,j都找到后交换数值
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=base;//交换i,j相遇位置数值和基准数
quisort(left,i-1,a);//在基准数左边重复上述过程,即递归左边
quisort(i+1,right,a);//在基准数右边重复上述过程,即递归右边
}
void quicksort(int a[],int size)//实际上一会在主函数中要调用的是这个函数
{
quisort(0,size-1,a);
/*用来验证排序是否可行的输出
cout<<"快速择排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
void shellsort(int a[],int size)//希尔排序
{
int h=1;
while(h<size/3)
h=3*h+1;
while(h>=1)
{
for(int i=h;i<size;++i)
{
for(int j=i;j>=h&&a[j]<a[j-h];j-=h)
{
int t=a[j];
a[j]=a[j-h];
a[j-h]=t;
}
}
h=h/3;
}
/*用来验证排序是否可行的输出
cout<<"希尔排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
void exchange(int a[],int i,int j)//堆排序的交换函数
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
void heapify(int a[],int i ,int size)//堆排序的堆化函数
{
int left=2*i+1;//因为堆顶上面还有一个树根,所以2i和2i+1要都+1
int right=2*i+2;
int max=i;//当前父节点为最大
if(left<size&&a[left]>a[max])
max=left;//如果有左节点,且左节点值更大,则交换
if(right<size&&a[right]>a[max])
max=right;//如果有右节点,且右节点值更大,则交换
if(max!=i)
{
exchange(a,i,max);//最大值不是当前节点,则交换
heapify(a,max,size);//交换后子节点值已经变了,需要再次堆化调整
}
}
void heapsort(int a[],int size)//堆排序
{
//构建大顶堆
for(int i=size/2-1;i>=0;i--)
{
heapify(a,i,size);
}
//交换堆顶元素和尾部元素
for(int j=size-1;j>0;j--)
{
exchange(a,0,j);
size--;
heapify(a,0,size);
}
/*用来验证排序是否可行的输出
cout<<"堆排序:"<<endl;
for(int ii=0;ii<size;ii++)
cout<<a[ii]<<' ';
cout<<endl;
*/
}
int main()
{
int randomnum[50000];
int a[50000];
srand(time(0));//设置种子,每回种下的种子不一样,得到的随机数不一样
int size;
cout<<"输入生成伪随机数的数目:"<<endl;
cin>>size;
for(int i=0;i<size;i++)
{
a[i]=rand()%size;
int j=i;
while(j--)
{
if(a[i]==a[j])//与之前的随机数比较,重复就再生成随机数,直到与之前不同
{
a[i]=rand()%size;
j=i;
}
}
randomnum[i]=a[i];//把生成的随机数存储到数组中
}
int p=1;
while (p)//p不是false,所以会一直循环下去,这样就可以在执行完菜单中的某个选项之后,返回最初菜单
{
int a;
cout<<"--------菜单--------"<<endl;
cout<<"1.输出伪随机数"<<endl;
cout<<"2.输出各个排序耗时"<<endl;
cout<<"3.退出菜单"<<endl;
cout<<"--------------------"<<endl;
cout<<endl;
cout<<"请输入选项序号:";
cin>>a;
switch(a)
{
case 1:
cout<<endl;
if(a==1)//输出伪随机数
{
for(int j=0;j<size;j++)
cout<<randomnum[j]<<' ';
cout<<endl;
}
cout<<endl;
break;
case 2:
cout<<endl;
clock_t start1,end1,start2,end2,start3,end3,start4,end4,start5,end5,start6,end6;
double totaltime1,totaltime2,totaltime3,totaltime4,totaltime5,totaltime6;
start4=clock();
quicksort(randomnum,size);
end4=clock();
totaltime4=(double)(end4-start4)/CLOCKS_PER_SEC;
cout<<"快速排序耗时 "<<totaltime4<<" 秒"<<endl;
start5=clock();
shellsort(randomnum,size);
end5=clock();
totaltime5=(double)(end5-start5)/CLOCKS_PER_SEC;
cout<<"希尔排序耗时 "<<totaltime5<<" 秒"<<endl;
start2=clock();
directsort(randomnum,size);
end2=clock();
totaltime2=(double)(end2-start2)/CLOCKS_PER_SEC;
cout<<"直接排序耗时 "<<totaltime2<<" 秒"<<endl;
start1=clock();
bubblesort(randomnum,size);
end1=clock();
totaltime1=(double)(end1-start1)/CLOCKS_PER_SEC;
cout<<"起泡排序耗时 "<<totaltime1<<" 秒"<<endl;
start3=clock();
selectsort(randomnum,size);
end3=clock();
totaltime3=(double)(end3-start3)/CLOCKS_PER_SEC;
cout<<"简单选择排序耗时 "<<totaltime3<<" 秒"<<endl;
start6=clock();
heapsort(randomnum,size);
end6=clock();
totaltime6=(double)(end6-start6)/CLOCKS_PER_SEC;
cout<<"堆排序耗时 "<<totaltime6<<" 秒"<<endl;
cout<<endl;
break;
case 3:
p=false;
break;
default:
cout<<"没有此选项!"<<endl;
break;
}
}
cout<<endl;
cout<<"退出菜单成功!"<<endl;
return 0;
}
总的来说,数据较少时,各个排序速度都比较快,相差不大;当数据较大时,可以
明显看出快速排序、希尔排序、堆排序、直接排序明显快于起泡排序和简单选择
排序。