C++ 排序算法实现 及 性能比较


#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
以上时间单位为毫秒
可以看出快排,堆排,希尔,归并算法效率还是非常高的,计数排序虽然速度是最快的,但是
以牺牲内存作为代价了,如果小范围排序,计数排序还是可以考虑下的。
基数排序比以上几种要稍慢些,但也不是差太远。
性能最不乐观的就是冒泡了。

    原文作者:排序算法
    原文地址: https://blog.csdn.net/lanwanjunxixihaha/article/details/50637145
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞