#include <iostream>
#include <queue>
#include <math.h>
#include <WINDOWS.H>
#include <time.h>
typedef int ArrayElemType;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//计数排序
void CountSort(ArrayElemType arr[],int size){
int max=arr[0],min=arr[0],i=0;
for(i=1;i<size;i++){
if(max<arr[i]){
max=arr[i];
}
if(min>arr[i]){
min=arr[i];
}
}
if(min<0)return;
int countSize=max+1;
int *count = new int[countSize];
ArrayElemType *sort = new ArrayElemType[size];
memset(count,0,countSize*4);
for(i=0;i<size;i++){
count[arr[i]]++;
}
for(i=1;i<countSize;i++){
count[i]+=count[i-1];
}
for(i=size-1;i>=0;i--){
int rank=count[arr[i]]--;
sort[rank-1]=arr[i];
}
memcpy(arr,sort,size*sizeof(ArrayElemType));
delete[] count;
delete[] sort;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//快排基准数归位,从小到大排序
int Partition(ArrayElemType array[],int low,int high){
ArrayElemType pivot = array[low];
while(low<high){
while(low<high&&array[high]>=pivot)high--;
array[low]=array[high];
while(low<high&&array[low]<=pivot)low++;
array[high]=array[low];
}
array[low]=pivot;
return low;
}
//快排
void QuickSort(ArrayElemType array[],int low,int high){
if(low>=high)
return;
int mid=Partition(array,low,high);
QuickSort(array,low,mid-1);
QuickSort(array,mid+1,high);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef int HeapElemType;
#define HeapLeft(i) (2*i+1)
#define HeapRight(i) (2*i+2)
#define HeapParent(i) ((i-1)/2)
void InitMinHeap(HeapElemType arr[],int size){
int cur=0,curVal;
for(int i=size/2-1;i>=0;i--){
cur=i;
curVal=arr[cur];
for(int j=HeapLeft(cur);j<size;j=HeapLeft(j)){
if(j+1<size&&arr[j]>arr[j+1])
j++;
if(curVal>arr[j]){
arr[cur]=arr[j];
cur=j;
}else{
break;
}
}
arr[cur]=curVal;
}
}
int MinHeapDelete(HeapElemType arr[],int size){
int temp=arr[0];
arr[0]=arr[size-1];
arr[size-1]=temp;
int curVal=arr[0],cur=0;
size--;
for(int j=HeapLeft(cur);j<size;j=HeapLeft(j)){
if(j+1<size&&arr[j]>arr[j+1])
j++;
if(curVal>arr[j]){
arr[cur]=arr[j];
cur=j;
}else{
break;
}
}
arr[cur]=curVal;
return size;
}
//堆排序
void MinHeapSort(HeapElemType arr[],int size){
while(size>1){
size=MinHeapDelete(arr,size);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//a为前半部分,b为后半部分,合并的过程理解成排序的过程,c是辅助数组
void MergeArray(ArrayElemType a[],int sa,ArrayElemType b[],int sb,ArrayElemType c[]){
int ia=0,ib=0,ic=0,i=0;
while(ia<sa&&ib<sb){
if(a[ia]<b[ib]){
c[ic++]=a[ia++];
}else{
c[ic++]=b[ib++];
}
}
while(ia<sa){
c[ic++]=a[ia++];
}
while(ib<sb){
c[ic++]=b[ib++];
}
while(i<ic){
a[i]=c[i];
i++;
}
}
void MergeSortRecursion(ArrayElemType a[],int left,int right,ArrayElemType c[]){
if(left==right)
return;
int mid=(left+right)/2;
MergeSortRecursion(a,left,mid,c);
MergeSortRecursion(a,mid+1,right,c);
MergeArray(a+left,mid-left+1,a+mid+1,right-mid,c);
//ShowArray(a+left,right-left+1);
}
//归并排序
void MergeSort(ArrayElemType a[],int size){
int *c=new int[size];
MergeSortRecursion(a,0,size-1,c);
delete[] c;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//希尔排序
void ShellSort(ArrayElemType array[],int arrlen){
int i,j;
ArrayElemType e;
for(int gap=arrlen/2;gap>0;gap/=2){
for(i=gap;i<arrlen;i++){
e=array[i];
for(j=i;j-gap>=0&&e<array[j-gap];j-=gap){
array[j]=array[j-gap];
}
array[j]=e;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//基数排序
#define GetNumber(num,idx) (num/((int)pow(10,idx-1))%10)
void RadixSort(ArrayElemType arr[],int size,int digit){
static int count[10];
ArrayElemType *sort = new ArrayElemType[size];
int i=0,digitVal=0,isAllZero=true;
for(int idx=1;idx<=digit;idx++){
memset(count,0,40);
isAllZero=true;
for(i=0;i<size;i++){
digitVal=GetNumber(arr[i],idx);
if(digitVal!=0){
isAllZero=false;
}
count[digitVal]++;
}
if(isAllZero)
break;
for(i=1;i<10;i++){
count[i]+=count[i-1];
}
for(i=size-1;i>=0;i--){
int rank=count[GetNumber(arr[i],idx)]--;
sort[rank-1]=arr[i];
}
memcpy(arr,sort,size*sizeof(ArrayElemType));
}
delete[] sort;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//折半插入排序
void BinInsertSort(ArrayElemType array[],int arrlen){
int i,j,left,right,mid;
ArrayElemType e;
for(i=1;i<arrlen;i++){
e=array[i];
left=0;
right=i-1;
while(left<=right){
mid=(left+right)/2;
if(array[mid]<e)
left=mid+1;
else if(array[mid]>e)
right=mid-1;
else{
left=mid;
break;
}
}
for(j=i;j>left;j--){
array[j]=array[j-1];
}
array[left]=e;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//插入排序
void InsertSort(ArrayElemType array[],int arrlen){
int i,j;
ArrayElemType e;
for(i=1;i<arrlen;i++){
e=array[i];
for(j=i;j>0&&e<array[j-1];j--){
array[j]=array[j-1];
}
array[j]=e;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//选择排序
void SelectSort(ArrayElemType arr[],int size){
ArrayElemType minV=0,minP=0;
for(int i=0;i<size;i++){
minV=arr[i];
minP=i;
for(int j=i+1;j<size;j++){
if(minV>arr[j]){
minP=j;
minV=arr[j];
}
}
minV=arr[i];
arr[i]=arr[minP];
arr[minP]=minV;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//顺序存储冒泡排序
void BubbleSort(ArrayElemType array[],int low,int high){
if(low>=high)
return;
bool hasBubble=false;
ArrayElemType e;
for(int i=low;i<=high;i++){
hasBubble=false;
for(int j=high;j>i;j--){
if(array[j]<array[j-1]){
hasBubble=true;
e=array[j];
array[j]=array[j-1];
array[j-1]=e;
}
}
if(!hasBubble)
return;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//性能测试
struct MyTick{
MyTick(){
QueryPerformanceFrequency(&m_liPerfFreq);
}
~MyTick(){
}
void start(){
QueryPerformanceCounter(&m_liPerfStart);
}
long stop(){
QueryPerformanceCounter(&liPerfNow);
interval=( ((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000)/m_liPerfFreq.QuadPart);
return interval;
}
void show(){
std::cout<<interval<<std::endl;
}
long interval;
LARGE_INTEGER m_liPerfFreq;
LARGE_INTEGER m_liPerfStart;
LARGE_INTEGER liPerfNow;
};
int main(){
ArrayElemType randArr[50000],testArr[50000];
int randSize=15000;
bool showResult=false;
MyTick tick;
srand(clock());
for(;randSize<=50000;randSize+=5000){
std::cout<<"==============数据规模:"<<randSize<<"=============="<<std::endl;
for(int i=0;i<randSize;i++){
randArr[i]=rand();
}
memcpy(testArr,randArr,randSize*4);
tick.start();
CountSort(testArr,randSize);
std::cout<<"CountSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
QuickSort(testArr,0,randSize-1);
std::cout<<"QuickSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
InitMinHeap(testArr,randSize);
MinHeapSort(testArr,randSize);
std::cout<<"MinHeapSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
MergeSort(testArr,randSize);
std::cout<<"MergeSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
ShellSort(testArr,randSize);
std::cout<<"ShellSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
RadixSort(testArr,randSize,5);
std::cout<<"RadixSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
BinInsertSort(testArr,randSize);
std::cout<<"BinInsertSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
InsertSort(testArr,randSize);
std::cout<<"InsertSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
SelectSort(testArr,randSize);
std::cout<<"SelectSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
memcpy(testArr,randArr,randSize*4);
tick.start();
BubbleSort(testArr,0,randSize-1);
std::cout<<"BubbleSort ";
tick.stop();
tick.show();
if(showResult)ShowArray(testArr,randSize);
}
system("Pause");
return 0;
}
输出结果如下:
==============数据规模:15000==============
CountSort 1
QuickSort 4
MinHeapSort 5
ShellSort 6
MergeSort 6
RadixSort 24
BinInsertSort 273
InsertSort 352
SelectSort 445
BubbleSort 1263
==============数据规模:20000==============
CountSort 1
QuickSort 5
MinHeapSort 6
ShellSort 8
MergeSort 7
RadixSort 32
BinInsertSort 482
InsertSort 621
SelectSort 790
BubbleSort 2246
==============数据规模:25000==============
CountSort 2
QuickSort 6
MinHeapSort 8
ShellSort 11
MergeSort 11
RadixSort 39
BinInsertSort 753
InsertSort 974
SelectSort 1235
BubbleSort 3526
==============数据规模:30000==============
CountSort 2
QuickSort 8
MinHeapSort 9
ShellSort 12
MergeSort 11
RadixSort 47
BinInsertSort 1100
InsertSort 1419
SelectSort 1766
BubbleSort 5081
==============数据规模:35000==============
CountSort 2
QuickSort 9
MinHeapSort 11
ShellSort 15
MergeSort 13
RadixSort 55
BinInsertSort 1480
InsertSort 1913
SelectSort 2408
BubbleSort 6885
==============数据规模:40000==============
CountSort 2
QuickSort 10
MinHeapSort 12
ShellSort 18
MergeSort 15
RadixSort 63
BinInsertSort 1938
InsertSort 2506
SelectSort 3153
BubbleSort 9070
==============数据规模:45000==============
CountSort 3
QuickSort 11
MinHeapSort 14
ShellSort 20
MergeSort 17
RadixSort 70
BinInsertSort 2446
InsertSort 3142
SelectSort 3984
BubbleSort 11445
==============数据规模:50000==============
CountSort 3
QuickSort 13
MinHeapSort 15
ShellSort 24
MergeSort 19
RadixSort 78
BinInsertSort 2997
InsertSort 3861
SelectSort 4906
BubbleSort 14035
以上时间单位为毫秒
可以看出快排,堆排,希尔,归并算法效率还是非常高的,计数排序虽然速度是最快的,但是
以牺牲内存作为代价了,如果小范围排序,计数排序还是可以考虑下的。
基数排序比以上几种要稍慢些,但也不是差太远。
性能最不乐观的就是冒泡了。