您的位置:首页 > 编程语言 > C语言/C++

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

以上时间单位为毫秒

可以看出快排,堆排,希尔,归并算法效率还是非常高的,计数排序虽然速度是最快的,但是

以牺牲内存作为代价了,如果小范围排序,计数排序还是可以考虑下的。

基数排序比以上几种要稍慢些,但也不是差太远。

性能最不乐观的就是冒泡了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息