C++ 排序算法实现 及 性能比较
2016-02-05 10:24
507 查看
#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
以上时间单位为毫秒
可以看出快排,堆排,希尔,归并算法效率还是非常高的,计数排序虽然速度是最快的,但是
以牺牲内存作为代价了,如果小范围排序,计数排序还是可以考虑下的。
基数排序比以上几种要稍慢些,但也不是差太远。
性能最不乐观的就是冒泡了。
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例