非比较排序
计数排序
计数排序算法不是一个基于比较的排序算法,而且一种稳定的排序算法。
计数排序该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。
计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。
代码实现:#pragmaonce#include<assert.h>//计数排序////选取最大的数,选取最小的数,开辟Max-Min+1个空间voidGetMinMax(int*a,intsize,int*max,int*min){assert(a);for(inti=0;i<size;i++){if(a[i]<*min){*min=a[i];}if(a[i]>*max){*max=a[i];}}return;}voidCountSort(int*a,intsize){assert(a);intmax=a[0];intmin=a[0];GetMinMax(a,size,&max,&min);intnewsize=max-min+1;int*count=newint[newsize];memset(count,0,(sizeof(int))*newsize);for(intj=0;j<size;j++){(count[a[j]-min])++;}intindex=0;for(intk=0;k<newsize;k++){intnumber=count[k];while(number>0){a[index++]=k+min;number--;}}delete[]count;return;}
测试案例:
voidCountSortTest(){intarray1[]={12,5,18,19,0,5,7,3,6};CountSort(array1,sizeof(array1)/sizeof(int));Print(array1,sizeof(array1)/sizeof(int));intarray2[]={12,5,3,18,3,19,0,5,3,7,3,6};CountSort(array2,sizeof(array2)/sizeof(int));Print(array2,sizeof(array2)/sizeof(int));return;}
基数排序
(radixsort)则是属于“分配式排序”(distributionsort),基数排序法又称“桶子法”(bucketsort)或binsort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。
以MLD为例,如图:
代码实现://基数排序//得到数据的最大位数intGetMaxRadix(int*a,size_tsize){intradix=1;intmax=10;for(size_ti=0;i<size;i++){while(a[i]>max){radix+=1;max*=10;}}returnradix;}//得到数据某一位数intData_k_Bit(intdata,intk){for(inti=1;i<k;i++){data/=10;}returndata%10;}//从低位到高位排序voidLSDSort(inta[],size_tsize){assert(a);intmaxRadix=GetMaxRadix(a,size);intcount[10]={0};//存放尾数为0-9的个数intstart[10]={0};//开始存放数据的位置int*bucket=newint[size];//计数个位分别为0—9的个数for(inti=1;i<=maxRadix;++i){memset(count,0,sizeof(count));for(size_tj=0;j<size;++j){intnum=Data_k_Bit(a[j],i);count[num]++;}start[0]=0;size_tindex=1;for(;index<10;index++){start[index]=start[index-1]+count[index-1];}for(size_tj=0;j<size;++j){intnum=Data_k_Bit(a[j],i);bucket[start[num]++]=a[j];}memcpy(a,bucket,sizeof(int)*size);}delete[]bucket;}voidPrint(int*a,intsize){assert(a);for(inti=0;i<size;i++){cout<<a[i]<<"";}cout<<endl;return;}voidMSDSort(int*a,size_tsize){intcount[10]={0};intstart[10]={0};int*bucket=newint[size];intmaxRadix=GetMaxRadix(a,size);for(inti=maxRadix;i>=1;i--){memset(count,0,sizeof(count));for(size_tj=0;j<size;j++){intnum=Data_k_Bit(a[j],i);count[num]++;}for(intj=1;j<10;j++){start[j]=start[j-1]+count[j-1];}for(size_tj=0;j<size;j++){intnum=Data_k_Bit(a[j],i);bucket[start[num]++]=a[j];}memcpy(a,bucket,sizeof(int)*size);}delete[]bucket;//delete[]bucket;}
测试案例:
voidLSDSorTest(){intarray1[]={12,5,18,19,0,5,7,3,6};LSDSort(array1,sizeof(array1)/sizeof(int));Print(array1,sizeof(array1)/sizeof(int));intarray2[]={12,5,3,18,3,19,0,5,3,7,3,6};LSDSort(array2,sizeof(array2)/sizeof(int));Print(array2,sizeof(array2)/sizeof(int));return;}voidMSDSorTest(){intarray1[]={12,5,18,19,0,5,7,3,6};MSDSort(array1,sizeof(array1)/sizeof(int));Print(array1,sizeof(array1)/sizeof(int));intarray2[]={12,5,3,18,3,19,0,5,3,7,3,6};MSDSort(array2,sizeof(array2)/sizeof(int));Print(array2,sizeof(array2)/sizeof(int));return;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。