C++起泡排序,直接排序,简单选择排序,快速排序,希尔排序,堆排序排序速度对比(包括伪随机数组生成)

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;
}

总的来说,数据较少时,各个排序速度都比较快,相差不大;当数据较大时,可以
明显看出快速排序、希尔排序、堆排序、直接排序明显快于起泡排序和简单选择
排序。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要多菜有多菜的鸟

如果有帮到你,打个赏吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值