精华内容
下载资源
问答
  • 内部排序算法效率比较: 直接排序 起泡排序 快速排序 简单选择排序 堆排序 希尔排序
  • 各种内部排序算法的时间复杂度分析结果只给出了算法执行的时间的阶,或大概执行时间。设计和实现内部排序算法效率比较平台,通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观的感受。
  • 常见排序算法效率比较

    千次阅读 2018-12-16 18:45:08
    常⻅排序算法效率⽐较

    常⻅排序算法效率⽐较

    在这里插入图片描述

    展开全文
  • 实验课程算法分析与设计 实验名称几种排序算法的平均性能比较 验证型实验 实验目标 1 几种排序算法在平均情况下哪一个更快 2 加深对时间复杂度概念的理解 实验任务 1实现几种排序算法selectionsort, insertionsort,...
  • 算法课的一个小项目,语言python。代码实习7种排序算法,TK实现简单GUI,源码可以学习7中排序算法详细实现,和GUI的搭建,基本包含了常用GUI组件。
  • java排序算法效率比较

    2013-04-27 13:57:10
    java产生多个随机数写入文件中,比较四种排序算法效率
  • 八种排序算法效率比较

    万次阅读 2016-05-23 01:25:06
    最近有个数据结构课程设计的实验,是有关于排序算法之间的效率比较,我就顺便把它放上来了,并对各个算法执行的效率时间做了柱形统计图表。此次实验主要测试了8种排序算法:插入排序、快速排序、冒泡排序、希尔排序...

    http://terence2008.info/archives/sorting_compare.html

      从刚上大一那会儿学的C语言开始,就已经接触到了不少排序算法,但当时都只是为了完成简单的排序任务而已,而且所给的数据也不够多,所以看不出各个排序算法间的执行效率的优劣。最近有个数据结构课程设计的实验,是有关于排序算法之间的效率比较,我就顺便把它放上来了,并对各个算法执行的效率时间做了柱形统计图表。此次实验主要测试了8种排序算法:插入排序、快速排序、冒泡排序、希尔排序、简单选择排序、堆排序、归并排序、折半插入排序。

          总共建立了三种情况,分别是平均排序、最好情况排序、最坏情况排序。第一种情况就是使用了VC6.0下的随机数生成函数输出100000个随机数进行排序;第二种情况是100000个数本身已经按从小到大的顺序排列了;第三种情况就是100000个数全部是按逆序排列。代码如下:

    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include<windows.h>
    #define MAX 100000
     
    void InsSort(int r[],int length)
    {
    	int i,j;
    	for (i=2;i<=length;i++)
    	{
    		r[0]=r[i];
    		j=i-1;
    		while(r[0]<r[j])
    		{
    			r[j+1]=r[j];
    			j=j-1;
    		}
    		r[j+1]=r[0];
    	}
    }       //插入排序
     
    void swap(int &x,int &y)
    {
    	int z;
    	z=x;
    	x=y;
    	y=z;
    }
    int median3(int a[],int left,int right)
    {
    	int center=(left+right)/2;
    	if(a[left]>a[center])
    		swap(a[left],a[center]);
    	if(a[left]>a[right])
    		swap(a[left],a[right]);
    	if(a[center]>a[right])
    		swap(a[center],a[right]);
    	swap(a[center],a[right-1]);
    	return a[right-1];
    }
    void insertionsort(int a[],int n)
    {
    	int j,p;
    	int tmp;
    	for(p=1;p<=n;p++)
    	{
    		tmp=a[p];
    		for(j=p;j>0&&a[j-1]>tmp;j--)
    			a[j]=a[j-1];
    		a[j]=tmp;
    	}
    }
    void qsort(int a[],int left,int right)
    {
    	int i,j;
    	int pivot;
    	if(left+2<=right)
    	{
    		pivot=median3(a,left,right);
    		i=left;j=right-1;
    		for(;;)
    		{
    			while(a[++i]<pivot){}
    			while(a[--j]>pivot){}
    			if(i<j)
    				swap(a[i],a[j]);
    			else
    				break;
    		}
    		swap(a[i],a[right-1]);
    		qsort(a,left,i-1);
    		qsort(a,i+1,right);
    	}
    	else
    		insertionsort(a+left,right-left+1);
    }
    void quicksort(int a[],int n)
    {
    	qsort(a,0,n-1);
    }      //快速排序
     
    void BubbleSort(int r[],int length)
    {
    	int i,j,temp;
    	for(j=length;j>0;j--)
    		for(i=0;i<j-1;i++)
    			if(r[i]>r[i+1])
    			{
    				temp=r[i];
    				r[i]=r[i+1];
    				r[i+1]=temp;
    			}
    }      //冒泡排序
     
    void ShellInsert(int r[],int length,int delta)
    {
    	int i,j;
    	for(i=1+delta;i<=length;i++)
    		if(r[i]<r[i-delta])
    		{
    			r[0]=r[i];
    			for(j=i-delta;j>0&&r[0]<r[j];j-=delta)
    				r[j+delta]=r[j];
    			r[j+delta]=r[0];
    		}
    }
    void  ShellSort(int r[], int length, int delt[], int n)
    { 
    	int i;
    	for(i=0;i<=n-1;++i)
    		ShellInsert(r,length,delt[i]);
    }       //希尔排序
     
    void SelectSort(int r[],int length)
    {
    	int i,j,k;
    	int n;
    	int x;
        n=length;
    	for (i=1;i<=n-1;++i)
    	{
    		k=i;
    		for(j=i+1;j<=n;++j)
    			if(r[j]<r[k])
    				k=j;
    			if( k!=i)
    			{
    				x= r[i];
    				r[i]=r[k];
    				r[k]=x;
    			}
    	}
     
    }        //简单选择排序
     
    void sift(int r[],int k,int m)
    {
    	int t;
    	int i,j;
    	int x;
    	int finished;
    	t= r[k];
    	x=r[k];
    	i=k;
    	j=2*i;
    	finished=FALSE;
    	while(j<=m&&!finished)
    	{     
    		if(j<m&&r[j]< r[j+1])
    			j=j+1;
    		if(x>=r[j])
    			finished=TRUE;
    		else 
    		{
    			r[i]=r[j];
    			i=j;
    			j=2*i;
    		}
    	}
    	r[i] =t;
    }
    void crt_heap(int r[], int length)
    {
    	int i,n;
        n=length;
    	for (i=n/2;i>=1;--i) 
    		sift(r,i,n);
    }
    void HeapSort(int r[],int length)
    {
    	int i,n;
    	int b;
    	crt_heap(r,length);
    	n= length;
    	for (i=n;i>=2;--i)
    	{
    		b=r[1];
    		r[1]=r[i];
    		r[i]=b;
    		sift(r,1,i-1);
    	}
    }       //堆排序
     
    void merge(int a[],int tmparray[],int lpos,int rpos,int rightend)
    {
    	int i,leftend,numelements,tmppos;
    	leftend=rpos-1;
    	tmppos=lpos;
    	numelements=rightend-lpos+1;
    	while(lpos<=leftend && rpos<=rightend)
    		if(a[lpos]<=a[rpos])
    			tmparray[tmppos++]=a[lpos++];
    		else
    			tmparray[tmppos++]=a[rpos++];
    		while(lpos<=leftend)
    			tmparray[tmppos++]=a[lpos++];
    		while(rpos<=rightend)
    			tmparray[tmppos++]=a[rpos++];
    		for(i=0;i<numelements;i++,rightend--)
    			a[rightend]=tmparray[rightend];
    }
    void msort(int a[],int tmparray[],int left,int right)
    {
    	int center;
    	if(left<right)
    	{
    		center=(left+right)/2;
    		msort(a,tmparray,left,center);
    		msort(a,tmparray,center+1,right);
    		merge(a,tmparray,left,center+1,right);
    	}
    }
    void mergesort(int a[],int n)
    {
    	int *tmparray;
    	tmparray=(int*)malloc(n*sizeof(int));
    	if(tmparray!=NULL)
    	{
    		msort(a,tmparray,0,n-1);
    		free(tmparray);
    	}
    	else
    		printf("no space for tmp array!");
    }        //归并排序
     
    void BInsertSort(int num[],int n)
    {
    	int length=n;
    	int low,high,i,j,m;
    	for(i=2;i<=length;i++)
    	{
    	   num[0]=num[i];
    	   low=1;
    	   high=i-1;
    	   while(low<=high)
    	   {
    		   m=(low+high)/2;
    			if(num[0]<num[m])
    				high=m-1;
    			else
    				low=m+1;
    	   }
    	   for(j=i-1;j>=high+1;j--)
    		   num[j+1]=num[j];
    	   num[high+1]=num[0];
    	}
    }        //折半插入排序
     
    void main()
    {
    	long dwStart,dwStop,runtime;
    	int num[MAX],a[MAX],i,j;
    	dwStart=GetTickCount();
    	srand((unsigned)time(NULL));
    	for(i=0;i<MAX;i++)
    		num[i]=rand();	
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("生成%d个随机数运行了%ldms\n\n",MAX,runtime);
     
    	printf("********平均排序时间********\n");
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	InsSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用插入排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	quicksort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用快速排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	BubbleSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用冒泡排序运行了%ldms\n",runtime);
     
    	int delt[10]={100,80,60,40,20,10,5,3,2,1};
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	ShellSort(a,MAX,delt,10);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用希尔排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	SelectSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用简单选择排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	HeapSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用堆排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	mergesort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用归并排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=num[i];
    	dwStart=GetTickCount();
    	BInsertSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用折半插入排序运行了%ldms\n",runtime);
    	printf("****************************\n\n");
     
    	printf("******最好情况排序时间******\n");
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	InsSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用插入排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	quicksort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用快速排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	BubbleSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用冒泡排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	ShellSort(a,MAX,delt,10);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用希尔排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	SelectSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用简单选择排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	HeapSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用堆排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	mergesort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用归并排序运行了%ldms\n",runtime);
     
    	for(i=0;i<MAX;i++)
    		a[i]=i;
    	dwStart=GetTickCount();
    	BInsertSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用折半插入排序运行了%ldms\n",runtime);
    	printf("****************************\n\n");
     
    	printf("******最坏情况排序时间******\n");
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	InsSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用插入排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	quicksort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用快速排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	BubbleSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用冒泡排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	ShellSort(a,MAX,delt,10);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用希尔排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	SelectSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用简单选择排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	HeapSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用堆排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	mergesort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用归并排序运行了%ldms\n",runtime);
     
    	for(i=MAX-1,j=0;i<=0,j<MAX;i--,j++)
    		a[j]=i;
    	dwStart=GetTickCount();
    	BInsertSort(a,MAX);
    	dwStop=GetTickCount();
    	runtime=dwStop-dwStart;
    	printf("使用折半插入排序运行了%ldms\n",runtime);
    	printf("****************************\n");
     
    	printf("\n排序测试完成!");
    	getchar();
    }

          执行程序是个很漫长的过程,像对于冒泡排序之类的算法,十万个数的排序再好的机器也得算上半天,不过像快速排序之类的算法如果不给予足够多的数据的话,执行时间永远是0毫秒。所以为了测算精确和公平比较,时间长我就慢慢熬吧。。。以下是我用执行完后的结果做成的统计图表(ps:图表中的数据是我在学院机器上的结果,在自己电脑上时间肯定会少许多,就懒得再算一遍了,反正情况都一样~~):

          结果很明显,快速排序、堆排序、归并排序这三种执行效率最快,不过话说回来,冒泡排序的代码真的是最好写的!看来算法高效代码复杂与算法低下代码简单是个很辩证的关系啊!
    展开全文
  • 文章目录使用c/c++实现冒泡排序算法比较排序算法效率实现目的冒泡法排序和比较排序的实现方法普通比较排序算法冒泡排序算法结论 使用c/c++实现冒泡排序算法比较排序算法效率 实现目的 通过对比冒泡法排序和...

    使用c/c++实现冒泡排序算法和比较排序算法的效率

    实现目的

    通过对比冒泡法排序和普通的比较排序,阐述冒泡法的排序效率,从而达到更好的掌握冒泡法的目的

    冒泡法排序和比较排序的实现方法

    普通比较排序算法

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    /**
     * @brief    normal_sort
     *
     *     normal compare algorithm to sort data sequence form smallest ---> biggest
     *
     * @param    vec
     */
    void normal_sort(vector<int> &vec)
    {
    	int i, j;
    	int size;
    	int temp;
    
    	size = vec.size();
    
    	for(auto v : vec)
    	{
    		cout << v << " ";
    	}
    	cout << endl;
    	cout << endl;
    
    	for(i=0; i<size-1; ++i)
    	{
    		for(j=i+1; j<size; ++j)
    		{
    			if(vec.at(i) > vec.at(j) )
    			{
    				temp = vec.at(i);
    				vec.at(i) = vec.at(j);
    				vec.at(j) = temp;
    			}
    		}
    
    		for(auto v : vec)
    		{
    			cout << v << " ";
    		}
    		cout << endl;
    	}
    }
    
    int main(int argc, char **argv)
    {
    	vector<int> intvec;
    	vector<int> intvec1;
    
    	vector<int>().swap(intvec);
    	vector<int>().swap(intvec1);
    	intvec.push_back(4);
    	intvec.push_back(5);
    	intvec.push_back(7);
    	intvec.push_back(1);
    	intvec.push_back(8);
    	intvec.push_back(3);
    
    	intvec1.push_back(1);
    	intvec1.push_back(2);
    	intvec1.push_back(3);
    	intvec1.push_back(4);
    	intvec1.push_back(5);
    	intvec1.push_back(6);
    
    	cout << "num: the bigger is down to bottom, and the smaller is up to the top" << endl;
    	normal_sort(intvec);
    	cout << "num1: if sequence is alredy sort, just run once time" << endl;
    	normal_sort(intvec1);
    
    	return 0;
    }
    

    执行结果

    tony@Tech:~/linux/fight$ ./normal_sort 
    num: the bigger is down to bottom, and the smaller is up to the top
    4 5 7 1 8 3 
    
    1 5 7 4 8 3 
    1 3 7 5 8 4 
    1 3 4 7 8 5 
    1 3 4 5 8 7 
    1 3 4 5 7 8 
    num1: if sequence is alredy sort, just run once time
    1 2 3 4 5 6 
    
    1 2 3 4 5 6 
    1 2 3 4 5 6 
    1 2 3 4 5 6 
    1 2 3 4 5 6 
    1 2 3 4 5 6 
    

    冒泡排序算法

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    /**
     * @brief    bubble_sort
     *     
     *     bubble algorithm to sort data sequence form smallest ---> biggest
     *
     * @param    vec
     */
    void bubble_sort(vector<int> &vec)
    {
    	bool flag;
    	int i, j;
    	int size;
    	int temp;
    
    	size = vec.size();
    
    	for(auto v : vec)
    	{
    		cout << v << " ";
    	}
    	cout << endl;
    	cout << endl;
    
    	for(i=size-1, flag=true; i>1 && flag; --i)
    	{
    		flag = false;
    
    		for(j=0; j<i; ++j)
    		{
    			if(vec.at(j) > vec.at(j+1) )
    			{
    				temp = vec.at(j);
    				vec.at(j) = vec.at(j+1);
    				vec.at(j+1) = temp;
    				flag = true;
    			}
    		}
    
    		for(auto v : vec)
    		{
    			cout << v << " ";
    		}
    		cout << endl;
    	}
    }
    
    int main(int argc, char **argv)
    {
    	vector<int> intvec;
    	vector<int> intvec1;
    
    	vector<int>().swap(intvec);
    	vector<int>().swap(intvec1);
    	intvec.push_back(4);
    	intvec.push_back(5);
    	intvec.push_back(7);
    	intvec.push_back(1);
    	intvec.push_back(8);
    	intvec.push_back(3);
    
    	intvec1.push_back(1);
    	intvec1.push_back(2);
    	intvec1.push_back(3);
    	intvec1.push_back(4);
    	intvec1.push_back(5);
    	intvec1.push_back(6);
    
    	cout << "num: the bigger is down to bottom, and the smaller is up to the top" << endl;
    	bubble_sort(intvec);
    	cout << "num1: if sequence is alredy sort, just run once time" << endl;
    	bubble_sort(intvec1);
    
    	return 0;
    }
    

    执行结果

    tony@Tech:~/linux/fight$ ./bubble_sort 
    num: the bigger is down to bottom, and the smaller is up to the top
    4 5 7 1 8 3 
    
    4 5 1 7 3 8 
    4 1 5 3 7 8 
    1 4 3 5 7 8 
    1 3 4 5 7 8 
    num1: if sequence is alredy sort, just run once time
    1 2 3 4 5 6 
    
    1 2 3 4 5 6 
    tony@Tech:~/linux/fight$ gedit normal_sort.cpp 
    tony@Tech:~/linux/fight$ 
    

    结论

    通过比较两种算法的差异得知:

    • 冒泡排序算法:先把最大的值沉到最低下,最小的值一步一步以冒泡的方式向前移动,而如果已经排序好的序列,只需要执行一次,效率是最高的。

    • 比较排序:不管原来是否排好序,都是按照固定的次数排序,执行次数是固定的
      c o u n t e r = n ∗ ( n − 1 ) 2 counter = \frac{n*(n-1)}{2} counter=2n(n1)

    展开全文
  • 冒泡排序 插入排序 选择排序 快速排序 归并排序 交换排序 效率比较 代码结构清晰
  • 按严蔚敏《数据结构》教材中的数据结构,实现了多种排序算法的程序设计,并进行实际数据输入测试对比。
  • 排序算法之(9)--八种常用排序算法效率对比

    万次阅读 多人点赞 2018-05-20 11:37:05
    排序是数据处理中一种很重要也很常用的运算,一般情况下,排序操作在数据处理过程中要花费许多时间,为了提高计算机的运行效率,我们提出并不断改进各种各样的排序算法,这些算法也从不同角度展示了算法设计的重要...

    介绍

    排序是数据处理中一种很重要也很常用的运算,一般情况下,排序操作在数据处理过程中要花费许多时间,为了提高计算机的运行效率,我们提出并不断改进各种各样的排序算法,这些算法也从不同角度展示了算法设计的重要原则和技巧。

    分类

    这里写图片描述

    复杂度

    排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
    冒泡排序 O(n2) O ( n 2 ) O(n2) O ( n 2 ) O(n) O ( n ) O(1) O ( 1 ) 稳定
    选择排序 O(n2) O ( n 2 ) O(n2) O ( n 2 ) O(n2) O ( n 2 ) O(1) O ( 1 ) 不稳定
    插入排序 O(n2) O ( n 2 ) O(n2) O ( n 2 ) O(n) O ( n ) O(1) O ( 1 ) 稳定
    希尔排序 O(n1.3) O ( n 1.3 ) O(n2) O ( n 2 ) O(n) O ( n ) O(1) O ( 1 ) 不稳定
    快速排序 O(nlog2n) O ( n l o g 2 n ) O(n2) O ( n 2 ) O(nlog2n) O ( n l o g 2 n ) O(nlog2n) O ( n l o g 2 n ) 不稳定
    归并排序 O(nlog2n) O ( n l o g 2 n ) O(nlog2n) O ( n l o g 2 n ) O(nlog2n) O ( n l o g 2 n ) O(n) O ( n ) 稳定
    堆排序 O(nlog2n) O ( n l o g 2 n ) O(nlog2n) O ( n l o g 2 n ) O(nlog2n) O ( n l o g 2 n ) O(1) O ( 1 ) 不稳定
    基数排序 O(nk) O ( n ∗ k ) O(nk) O ( n ∗ k ) O(nk) O ( n ∗ k ) O(n+k) O ( n + k ) 稳定

    代码

    除了一个swap和test辅助函数,其余的是八种算法的函数全家桶,不方便看的话可以回到我前面的章节,不过没有讲原理,只有代码。

    #include<stdlib.h>
    #include<stdio.h>
    #include<time.h>
    #include<sys/timeb.h>
    
    //#define MAX 250000  //这个数字栈就溢出了
    #define MAX 2500000
    
    /*
    n种排序方法,都是从大到小排列
    没有太参考别人的程序,大部分是根据定义琢磨的
    如有疏漏,恳请批评指教
    */
    
    //辅助函数:交换两个变量
    void swap(int*a,int*p)
    {
        int temp = *a;
        *a = *p;
        *p = temp;
    }
    
    //---------------自己实现的各种排序算法----------------
    //冒泡排序
    //两两对比,把最大的一直挪到最后面
    //非常不怎样的一个算法,但确是大部分高校教的第一个算法
    void bubbleSort(int* arr,int len)
    {
        int i,j;
        //这个是上界
        for(i=0;i<len;i++)
        {
            //一般导数第i+1个以后都已经排好了
            for(j=1;j<len-i;j++)
            {
                //大的一直冒泡到最后面去
                if(arr[j-1]>arr[j])
                {
                    swap(&arr[j-1],&arr[j]);
                }
            }
        }
    }
    
    //选择排序
    //把最小的一个个放到第一第二第三个
    //已放好的叫有序区,没放好的是无序区,有序区一旦放好就不会变了
    void selectSort(int*arr,int len)
    {
        //i大循环,j大小对比
        int i,j;
        int temp,index;//临时对照变量
        for(i=0;i<len;i++)
        {
            //先假设无序区第一个是最小
            temp = arr[i];
            index = i;
            for(j=i+1;j<len;j++)
            {
                //找到无序区真正最小的
                if(arr[j]<temp)
                {
                    temp = arr[j];
                    index = j;
                }
            }
            //如果第一个就是最小的,就不用进行什么交换
            if(index==i)
            continue;
            //不然就交换无序区第一个数和无序区最小的数
            swap(&arr[i],&arr[index]);
        }
    }
    
    //插入排序
    //从第1个数开始,往后开始遍历,第i个数一定要放到使得前i个数都变成有序的。
    void insertSort(int* arr,int len)
    {
        int i,j;
        for(i=0;i<len;i++)
        {
            for(j=i;j>0;j--)
            {
                if(arr[j]<arr[j-1])
                {
                    swap(&arr[j],&arr[j-1]);
                }else
                {
                    //已经不比那个元素小了就提前退出
                    break;
                }
            }
        }
    }
    
    //希尔排序
    //插入排序的加强版,不是一次性进行插入,而是分成一拨拨来进行
    //比如奇数下标的为一拨,偶数下标的为一拨,然后再对分好的两拨进行插入排序
    //也就是一开始是隔一定step>1进行插入排序,最后的step=1
    //这个步长的变动方式有多种,可是是 step:=step/3+1
    //对大量的数据,排序效率明显比插入排序高
    void shellSort(int* arr,int len)
    {
        int step = len;
        //do while比较好,保证step为1还能再排一次
        do
        {
            //这句一定要放这里,不然步长为1就跳出去了,最后一次无法排序
            step = step/3 +1;
            int i,j,k;
            //分拨排序,一共有step拨
            for(i=0;i<step;i++)
            {
                for(j=i;j<len;j+=step)
                {
                    for(k=j;k>i;k-=step)
                    {
                        if(arr[k]<arr[k-step])
                        {
                            swap(&arr[k],&arr[k-step]);
                        }else
                        {
                            break;
                        }
                    }
                }
            }
        }while(step>1);
    
    }
    
    //快速排序
    //顾名思义,排得真的很快。用递归思想
    //每次找一个基准数,以其为参考点,比它小的放左边,大的放右边(这两堆内部可能是无序的)
    //再把分好的两堆各自找个基准数,按前面的步骤再来,直至数据不能再分,排序完毕
    //基准先挖出来,有i,j两个指针,一开始j往左挪,如果遇到比基准小的,填到基准位置
    //之后换i往后挪,遇到比基准大的,就放到j的那个坑。全部跑完后,基准丢到最后剩出来的那个坑。
    void quickSort(int* arr,int start,int end)
    {
        //递归最重要的就是设置退出条件,如下
        if(start>=end)
        {
            return;
        }
        int i = start;
        int j = end;
        int temp = arr[i];
        //如果右指针j一直没小于左指针i,一直跑
        while(i<j)
        {
            //先从右边找比基准小的,找到和基准交换,但要保留j值
            while(i<j)
            {
                if(arr[j]<temp)
                {
                    swap(&arr[j],&arr[i]);
                    break;
                }
                j--;
            }
    
            //右边找到一个比基准小的之后,轮到左边找比基准大的,然后和上面空出的j位置交换
            while(i<j)
            {
                if(arr[i]>temp)
                {
                    swap(&arr[j],&arr[i]);
                    break;
                }
                i++;
            }
    
        }
        //排左半区
        quickSort(arr,start,i-1);
        //排右半区
        quickSort(arr,i+1,end);
    }
    
    //归并排序
    //本质上是把两个已经排好的序列合并成一个
    //如果对一个随机序列的两两元素来看,那么每个元素都是排好的序列
    //可以把一个数组拆分成前后两半来做这件事
    //这个算法需要额外的辅助空间,用来存放归并好的结果
    void mergeSort(int* arr,int start,int end)
    {
        if(start>=end)
        {
            return;
        }
        int i = start;
        int mid = (start+end)/2;
        int j = mid + 1;
        mergeSort(arr,i,mid);
        mergeSort(arr,j,end);
    
        //合并
        //其实我觉得不用这个额外的空间也行,两个子序列再排一次能减少空间,不过速度肯定会有影响
        int* temp = (int*)malloc((end-start+1)*sizeof(int));
        int index = 0;
        //开始对比两个子序列,头部最小的那个数放到新空间
        while(i<=mid&&j<=end)
        {
            if(arr[i]<=arr[j])
            {
                temp[index++] = arr[i++];
            }else
            {
                temp[index++] = arr[j++];
            }
        }
        //总有一个序列是还没有放完的,这里再遍历一下没放完的
        while(i<=mid)
        {
            temp[index++] = arr[i++];
        }
        while(j<=end)
        {
            temp[index++] = arr[j++];
        }
        //排完再把新空间的元素放回旧空间
        int k = start;
        for(k;k<=end;k++)
        {
            //哎,temp的下标写错,排查了一个钟,真菜
            arr[k] = temp[k-start];
        }
        free(temp);
    }
    
    //堆排序
    /*
    这个堆是数据结构堆,不是内存malloc相关的那个堆--我曾经理解错n久
    根节点比孩子节点都大的叫大顶堆(包括子树的根),比孩子节点小的叫小顶堆
    从小到大排序用的是大顶堆,所以要先构造这种堆,然后把这个根的最大元素交换到最尾巴去
    每次拿走一个最大元素,待排序的队列就慢慢变短
    主要步骤1,初始化构造这种大顶堆,把堆顶最大的数放到最尾巴,数列长度减少1,再次构建大顶堆
    2,这时候只有堆顶元素不满足大顶堆,那么其实只要从堆顶元素开始慢慢微调而已,没必要再完全重新建堆,想要也可以,不过很浪费时间
    理解起来确实很难,涉及到完全二叉树
    孩子节点i的爸爸是i/2,爸爸节点的儿子是2i和2i+1。
    第一次初始化之后充分利用子树已经是大顶堆
    */
    void adjust(int* arr,int len,int index)
    {
        //调整函数,把孩子、父亲中的最大值放到父亲节点
        //index为待调整节点下标,一开始设它最大
        int max = index;
        int left = 2*index+1;//左孩子
        int right = 2*index+2;//右孩子
        if(left<len && arr[left] > arr[max])
        {
            max = left;
        }
        if(right<len && arr[right] > arr[max])
        {
            max = right;
        }
        //如果父亲节点不是最大
        if(max!=index)
        {
            //一旦上层节点影响了某个孩子节点,还要观察以这个孩子节点为父节点的子树是不是也不是大顶堆了
            swap(&arr[index],&arr[max]);
            //因为发生了交换,还要继续调整受到影响的孩子节点
            //***************************************
            adjust(arr,len,max);//这句话非常非常关键
            //***************************************
            /*
                只有父亲和孩子节点发生了交换,才有继续调整孩子的必要,如果无脑在不是这里面递归,堆排序的效果不会比冒泡好到哪去
                而如果写在了这里面,虽然还是pk不过快排,但好歹和快排的差距只缩小到个位数倍数的量级(小数据量的时候)
                堆排序一个优点是空间复杂度也不高
            */
        }
    }
    //主要排序部分
    void heapSort(int* arr,int len)
    {
        //初始化大顶堆
        //initHeap(arr,i,0);
        //从最后一个非叶子节点开始
        //第一次一定要从下至上一直排,一开始是乱序的
        int i = len/2-1;
        for(i;i>=0;i--)
        {
            adjust(arr,len,i);
        }
        swap(&arr[0],&arr[len-1]);
    
    
        //第二次之后,只需要从根节点从上到下调整,遇到没发生交换的直接可以退出循环了
        //微调得到大顶堆(因为只有堆顶不满足而已)
        int j = len -1; //去掉尾节点后的数组长度
        //把最大值交换到最后
        for(j;j>0;j--)
        {
            adjust(arr,j,0);
            swap(&arr[0],&arr[j-1]);
        }
    }
    
    
    //基数排序
    //radix sort,说是桶排bucket sort的一种,具体没仔细查证
    //对于整数,按个位数先排,再排十位,再排百位..
    //需要和原数组一样的额外的空间,用来临时存那些数字
    void radixSort(int* arr,int len,int max)
    {
        int n = 1;//位数 1 10 100 1000 ...
        int (*bucket)[len] = (int(*)[len])malloc(10*len*sizeof(int));//int[某数位为某尾数的所有数字][某尾数]
        int count[10] = {0};//某个数位0-9
        while(n<=max)
        {
            int i = 0;
            int digit;
            for(i = 0;i<len;i++)
            {
                digit = (arr[i]/n)%10;//某个数位的数字,如n=10,arr[i]为293,则这里就是求十位,即=9
                bucket[digit][count[digit]]= arr[i];
                count[digit] += 1;//记得每次找到一个位数为digit的,数量+1
    
            }
            //放回原数组
            i = 0;
            for(digit = 0;digit<10;digit++)
            {
                int j = 0;
                for(j = 0;j<count[digit];j++)
                {
                    arr[i++] = bucket[digit][j];
                }
                count[digit] = 0;//清空那个桶,准备下次放
            }
    
            n*=10;//位数10倍变化
        }
        free(bucket);
    }
    
    //---------------辅助函数等----------------
    //打印数组
    void printArr(int* arr,int len)
    {
        int i = 0;
        for(i;i<len;i++)
        {
            printf("%d\t",*(arr++));
        }
        printf("\n");
    }
    
    //计算时间,精确到毫秒
    long getTime()
    {
        struct timeb tb;
        ftime(&tb);
        //前面是毫秒,后面是微秒
        return tb.time*1000+tb.millitm;
    }
    
    //小型主函数
    void test()
    {
        //int a[MAX],a1[MAX],a2[MAX],a3[MAX],a4[MAX],a5[MAX],a6[MAX],a7[MAX];
        int* a = (int*)malloc(MAX*sizeof(int));
        int* a1 = (int*)malloc(MAX*sizeof(int));
        int* a2 = (int*)malloc(MAX*sizeof(int));
        int* a3 = (int*)malloc(MAX*sizeof(int));
        int* a4 = (int*)malloc(MAX*sizeof(int));
        int* a5 = (int*)malloc(MAX*sizeof(int));
        int* a6 = (int*)malloc(MAX*sizeof(int));
        int* a7 = (int*)malloc(MAX*sizeof(int));
        int i = 0;
        srand(time(NULL));
        for(i;i<MAX;i++)
        {
            int temp = rand()%(MAX+1);
    //        int temp = i;//升序测试
    //        int temp = MAX-i-1;//降序测试
    
            a[i] = temp;
            a1[i] = temp; 
            a2[i] = temp; 
            a3[i] = temp; 
            a4[i] = temp; 
            a5[i] = temp; 
            a6[i] = temp; 
            a7[i] = temp;
        }
    
    //    printArr(a,MAX);
    
        long t1 = getTime();
    
    
        //冒泡排序
    //    bubbleSort(a,MAX);
    //    printArr(a,MAX);
        long t2 = getTime();
        printf("冒泡排序排%d个随机数据耗时%ld毫秒\n",MAX,t2-t1);
    
        //选择排序
    //    selectSort(a1,MAX);
    //    printArr(a1,MAX);
        long t3 = getTime();
        printf("选择排序排%d个随机数据耗时%ld毫秒\n",MAX,t3-t2);
    
        //插入排序
    //    insertSort(a2,MAX);
    //    printArr(a2,MAX);
        long t4 = getTime();
        printf("插入排序排%d个随机数据耗时%ld毫秒\n",MAX,t4-t3);
    
        //希尔排序
        shellSort(a3,MAX);
    //    printArr(a3,MAX);
        long t5 = getTime();
        printf("希尔排序排%d个随机数据耗时%ld毫秒\n",MAX,t5-t4);
    
        //快速排序
        quickSort(a4,0,MAX-1);
    //    printArr(a4,MAX);
        long t6 = getTime();
        printf("快速排序排%d个随机数据耗时%ld毫秒\n",MAX,t6-t5);
    
        //归并排序
        mergeSort(a5,0,MAX-1);
    //    printArr(a5,MAX);
        long t7 = getTime();
        printf("归并排序排%d个随机数据耗时%ld毫秒\n",MAX,t7-t6);
    
        //堆排序
        heapSort(a6,MAX);
    //    printArr(a6,MAX);
        long t8 = getTime();
        printf("堆排序排%d个随机数据耗时%ld毫秒\n",MAX,t8-t7);
    
        //基数排序
        radixSort(a7,MAX,MAX);
        printArr(a7,MAX);
        long t9 = getTime();
        printf("基数序排%d个随机数据耗时%ld毫秒\n",MAX,t9-t8);
    
    }
    
    void main()
    {
        test();
    }
    

    运行结果:

    数据量较小的时候

    150000个随机数:
    这里写图片描述
    250000个随机数:
    这里写图片描述

    数据量较大的时候

    这里写图片描述
    加入了个新成员基数排序
    250w个随机数:
    这里写图片描述
    2500w个数据:
    这里写图片描述
    最后一个挂掉的是基数排序,我的内存只有2G,基数排序用了桶的原理,需要额外空间。
    千万不要拿冒泡去试上面这个数据量,除非你真的很闲。

    数据原本有序且是升序的时候

    这里写图片描述

    数据原本有序且是降序的时候

    这里写图片描述


    后话

    注意,如果原本的序列就是有序(升序或降序)的,快排基本就是和冒泡是兄弟了,慢到让你怀疑人生。希尔、归并、堆排、基数基本影响不大。可见如果数据本来就只有微小的无序,还是不要用快排了。

    展开全文
  • 直接插入排序,折半插入排序,希尔排序,冒泡排序,一趟快速排序,快速排序,直接选择排序,堆排序相关代码及效率比较
  • 计算程序执行时间,准确比较各种排序算法效率
  • 各种内部排序算法效率比较的MFC源程序,用一个函数记录时间,输出单位为ms 内含冒泡,选择,插入,快速,归并,堆六种排序算法,代码简洁明了
  • 通过几组有代表意义的随机数据的比较,算出几种这几种排序算法的关键字比较次数和关键字移动次数,以便我们分析算法效率。 1、通过修改程序,实现程序在要求的数据量下求出以下六种内部排序算法的移动次数和比较次数...
  • 各种排序算法效率分析比较及源代码 C语言实现 各种排序包括: 直接插入排序,折半插入排序,2—路插入排序和表插入排序;希尔排序和链式基数排序;起泡排序,快速排序,归并排序;简单选择排序,树形选择排序和堆...
  • Python实现常见排序算法速度比较

    千次阅读 2018-08-31 23:04:45
    下面分类列举下常见排序算法: ①冒泡排序 冒泡排序的原理是对序列进行遍历,遍历过程中如果发现相邻两个元素,左边的元素大于右边,则进行交换,一次遍历之后最大的元素被移动到对尾,然后进行第二次遍历,直到...
  • 下面我们通过一个实验案例来进行上述4种排序算法效率的直观比较。 实验内容:创建4个具有相同初始化长度、初始化元素内容和元素顺序的,长度为100000的正整数数组,数组中填充的全部都是取值范围在[0,100000]之间的...
  • 五种内部排序算法性能比较——C++

    千次阅读 2018-07-29 17:24:05
    五种内部排序算法性能比较 1.直接插入排序算法 将一个待排序的记录插入到若干个已排好序的有序记录中的适当位置,从而得到一个新的、记录数增加1的有序数据序列,直到插入完成。在最开始,整个有序数据序列只有...
  • 排序算法-八大排序实现和性能比较

    万次阅读 多人点赞 2017-12-28 12:29:41
      常见的八大排序算法,他们之间关系如下:   本文的开发语言是用Java,为了更好的演示,这里先新建一个工具类NumberUtils ,用来生成随机数组和打印排序前后数组的内容。 public class NumberUtils { /*...
  • 数据结构-各种排序算法效率对比图

    万次阅读 2014-02-13 06:01:14
    排序法 平均时间复杂度 最差情形 稳定度 额外空间 备注 冒泡排序 O(n2)  O(n2) 稳定 O(1) n小时较好 交换排序 O(n2)  O(n2) 不稳定 O(1) n小时较好 选择排序 O(n2) O(n2) 不稳定 O(1) n小时较好 插入排序 ...
  • 排序算法的好坏,主要是看排序效率,排序效率的一个重要指标就是速度,速度是影响排序算法的最主要因素。 一般来说,判断一个算法的优劣,可以从以下两个方面进行: 算法的复杂度:以O表示,往往从最差,平均,...
  • 数据结构排序算法综合运用及比较(C语言实现)

    千次阅读 多人点赞 2020-04-29 20:30:09
    排序算法综合及效率比较 实验目的 实验内容 实验要求 实验步骤 概要设计 详细设计 软件测试 设计总结 源程序代码 1.实验目的 (1)熟练掌握几种经典排序的算法(如冒泡排序、选择排序、插入排序、希尔排序、折半...
  • 常见排序算法总结及性能比较

    千次阅读 2018-09-24 14:33:39
    常见排序算法总结及性能比较一.常见排序算法有哪些二. 插入排序1.直接插入排序2.希尔排序三.选择排序1.直接选择排序2.堆排序四.交换排序1.冒泡排序2.快速排序五.归并排序1.归并排序六.各算法性能比较 一.常见排序...
  • 本文实例讲述了PHP四种排序算法实现及效率分析。分享给大家供大家参考,具体如下: PHP的四种基本排序算法为:冒泡排序、插入排序、选择排序和快速排序。 下面是我整理出来的算法代码: 1. 冒泡排序: 思路:对数组...
  • 尽管这个算法是最简单了解和实作的排序算法之一,但它对于少数元素之外的数列排序是很没有效率的。 冒泡排序是与插入排序拥有相等的执行时间,但是两种法在需要的交换次数却很大地不同。在最坏的情况,冒泡排序需要O...
  • 本文实例讲述了Python八大常见排序算法定义、实现及时间消耗效率分析。分享给大家供大家参考,具体如下: 昨晚上开始总结了一下常见的几种排序算法,由于之前我已经写了好几篇排序的算法的相关博文了现在总结一下的...
  • 主要介绍了JavaScript数据结构与算法之基本排序算法定义与效率比较,结合实例形式详细总结分析了javascript排序算法中的冒泡、选择、插入等排序算法原理与操作技巧,需要的朋友可以参考下
  • 一、排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,... 时间复杂度:即时间性能,高效率排序算法应该是具有尽可能少的关键字比较次数和记录的移动次数 空间复杂度:主要是执
  • 关于几种排序算法的时间性能比较

    千次阅读 2018-08-22 23:43:06
    以前经常看到各种排序算法,今天也对以下6种排序算法的性能做了一次测试: 1. 冒泡排序 O(n^2) /** 冒泡排序 @Param {[]int} arr 整形切片 */ func BubbleSort(arr []int) { length := len(arr) for i := ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 254,931
精华内容 101,972
关键字:

排序算法效率比较