7中排序算法的性能比较


排序是计算机算法中非常重要的一项,而排序算法又有不少实现方法,那么哪些排序算法比较有效率,哪些算法在特定场合比较有效,下面将用C++实现各种算法,并且比较他们的效率,让我们对各种排序有个更深入的了解。

1、冒泡排序
//n^2 	冒泡排序V[n]不参与排序
void BubbleSort (int V[], int n ) 
{
    bool exchange;     //设置交换标志置
    for ( int i = 0; i < n; i++ ){
        exchange=false;
        for (int j=n-1; j>i; j--) { //反向检测,检查是否逆序
            if (V[j-1] > V[j]) //发生逆序,交换相邻元素
            { 
                int temp=V[j-1]; 
                V[j-1]=V[j];
                V[j]=temp; 
                exchange=true;//交换标志置位
            }
        }
        
        if (exchange == false)
            return; //本趟无逆序,停止处理
    }
}

2、插入排序
//插入排序,L[begin],L[end]都参与排序
void InsertionSort ( int L[], const int begin, const int end)
{
    //按关键码 Key 非递减顺序对表进行排序
    int temp;
    int i, j;
    for ( i = begin; i < end; i++ ) 
    {
        if (L[i]>L[i+1]) 
        {
            temp = L[i+1]; 
            j=i;
            do 
            {
                L[j+1]=L[j];
                if(j == 0)
                {
                    j--;
                    break;
                }
                j--;
                
            } while(temp<L[j]);
            L[j+1]=temp;
        }
    }
}

3、快速排序
//n*logn
//快速排序A[startingsub],A[endingsub]都参与排序
void QuickSort( int A[], int startingsub, int endingsub)
{
    if ( startingsub >= endingsub )
        ;
    else{
        int partition;
        int q = startingsub;
        int p = endingsub;
        int hold;
        
        do{
            for(partition = q ; p > q ; p--){
                if( A[q] > A[p]){
                    hold = A[q];
                    A[q] = A[p];
                    A[p] = hold;
                    break;
                }
            }
            for(partition = p; p > q; q++){
                if(A[p] < A[q]){
                    hold = A[q];
                    A[q] = A[p];
                    A[p] = hold;
                    break;
                }
            }
            
        }while( q < p );
        QuickSort( A, startingsub, partition - 1 );
        QuickSort( A, partition + 1, endingsub );
    }
}

4、希尔排序
//希尔排序,L[left],L[right]都参与排序
void Shellsort( int L[], const int left, const int right)
{
    int i, j, gap=right-left+1; //增量的初始值
    int temp;
    do{
        gap=gap/3+1; //求下一增量值
        for(i=left+gap; i<=right; i++)
            //各子序列交替处理
            if( L[i]<L[i-gap]){ //逆序
                temp=L[i]; j=i-gap; 
                do{
                    L[j+gap]=L[j]; //后移元素
                    j=j-gap; //再比较前一元素
                }while(j>left&&temp<L[j]);
                L[j+gap]=temp; //将vector[i]回送
            }
    }while(gap>1);
}

5、计数排序
//n
//计数排序,L[n]不参与排序
void CountingSort( int L[], const int n )
{
    int i,j;
    const int k =1001;
    int tmp[k];
    int *R;
    R = new int[n];
    for(i=0;i<k;i++) tmp[i]= 0; 
    for(j=0;j<n;j++) tmp[L[j]]++; 
    //执行完上面的循环后,tmp[i]的值是L中等于i的元素的个数
    for(i=1;i<k;i++)
        tmp[i]=tmp[i]+tmp[i-1]; //执行完上面的循环后,
    //tmp[i]的值是L中小于等于i的元素的个数
    for(j=n-1;j>=0;j--) //这里是逆向遍历,保证了排序的稳定性
    {
        
        R[tmp[L[j]]-1] = L[j]; 
        //L[j]存放在输出数组R的第tmp[L[j]]个位置上
        tmp[L[j]]--; 
        //tmp[L[j]]表示L中剩余的元素中小于等于L[j]的元素的个数 
        
    }
    for(j=0;j<n;j++) L[j] = R[j];
}

6、基数排序
//基数排序
void printArray( const int Array[], const int arraySize );
int getDigit(int num, int dig);
const int radix=10; //基数
void RadixSort(int L[], int left, int right, int d){
//MSD排序算法的实现。从高位到低位对序列划分,实现排序。d是第几位数,d=1是最低位。left和right是待排序元素子序列的始端与尾端。
   int i, j, count[radix], p1, p2;
   int *auxArray;
   int M = 5;
   auxArray = new int[right-left+1];
   if (d<=0) return; //位数处理完递归结束
   if (right-left+1<M){//对于小序列可调用直接插入排序
       InsertionSort(L,left,right); return;
   }
   for (j=0; j<radix; j++) count[j]=0;
   for (i=left; i<=right; i++) //统计各桶元素的存放位置
       count[getDigit(L[i],d)]++;
   for (j=1; j<radix; j++) //安排各桶元素的存放位置
       count[j]=count[j]+count[j-1];
   for (i=right; i>=left; i--){ //将待排序序列中的元素按位置分配到各个桶中,存于助数组auxArray中
       j=getDigit(L[i],d); //取元素L[i]第d位的值
       auxArray[count[j]-1]=L[i]; //按预先计算位置存放
       count[j]--; //计数器减1
   }
   for (i=left, j=0; i<=right; i++, j++)    
       L[i]=auxArray[j]; //从辅助数组顺序写入原数组
   delete []auxArray;
    for (j=0; j<radix; j++){ //按桶递归对d-1位处理
       p1=count[j]+left; //取桶始端,相对位置,需要加上初值$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
       (j+1 <radix )?(p2=count[j+1]-1+left):(p2=right) ; //取桶尾端
     // delete []count;
     if(p1<p2){
       RadixSort(L, p1, p2, d-1); //对桶内元素进行基数排序 
     // printArray(L,10);
     }
   }
 
} 
int getDigit(int num, int dig)
{
    int myradix = 1;
/*    for(int i = 1;i<dig;i++)
    {
    myradix *= radix;
    }*/
    switch(dig)
    {
    case 1:
        myradix = 1;
        break;
case 2:
        myradix = 10;
        break;
case 3:
        myradix = 1000;
        break;
case 4:
        myradix = 10000;
        break;
default:
        myradix = 1;
        break;
    }
    return (num/myradix)%radix;
}

7、堆排序
//使用时注意将关键码加入
#ifndef MINHEAP_H
#define MINHEAP_H
#include <assert.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::cerr;
#include <stdlib.h>
//const int maxPQSize = 50; 
template <class Type> class MinHeap {
public: 
    MinHeap ( int maxSize );//根据最大长度建堆
    MinHeap ( Type arr[], int n );//根据数组arr[]建堆
    ~MinHeap ( ) { delete [] heap; }
    const MinHeap<Type> & operator = ( const MinHeap &R );//重载赋值运算符
    int Insert ( const Type &x );//插入元素
    int RemoveMin ( Type &x );//移除关键码最小的元素,并赋给x
    int IsEmpty ( ) const { return CurrentSize == 0; }//检查堆是否为空 
    int IsFull ( ) const { return CurrentSize == MaxHeapSize; }//检查对是否满
    void MakeEmpty ( ) { CurrentSize = 0; }//使堆空
private: 
    enum { DefaultSize = 50 };//默认堆的大小
    Type *heap; 
    int CurrentSize;
    int MaxHeapSize;
    void FilterDown ( int i, int m );//自上向下调整堆
    void FilterUp ( int i );//自下向上调整堆
};
template <class Type> MinHeap <Type>::MinHeap ( int maxSize )
{
    //根据给定大小maxSize,建立堆对象
    MaxHeapSize = (DefaultSize < maxSize ) ? maxSize : DefaultSize;     //确定堆大小
    heap = new Type [MaxHeapSize]; //创建堆空间
    CurrentSize = 0; //初始化
}
template <class Type> MinHeap <Type>::MinHeap ( Type arr[], int n )
{
    //根据给定数组中的数据和大小,建立堆对象 
    MaxHeapSize = DefaultSize < n ? n : DefaultSize;
    heap = new Type [MaxHeapSize]; 
    if(heap==NULL){cerr <<"fail" <<endl;exit(1);}
    for(int i =0; i< n; i++)
        heap[i] = arr[i]; //数组传送
    CurrentSize = n; //当前堆大小
    int currentPos = (CurrentSize-2)/2; //最后非叶
    while ( currentPos >= 0 ) { 
        //从下到上逐步扩大,形成堆
        FilterDown ( currentPos, CurrentSize-1 );
        currentPos-- ;
        //从currentPos开始,到0为止, 调整currentPos--; }
    }
}
template <class Type> void MinHeap<Type>::FilterDown ( const int start, const int EndOfHeap )
{
    // 结点i的左、右子树均为堆,调整结点i
    int i = start, j = 2*i+1; // j 是 i 的左子女
    Type temp = heap[i];
    while ( j <= EndOfHeap ) {
        if ( j < EndOfHeap && heap[j] > heap[j+1] )
            j++;//两子女中选小者
        if ( temp<= heap[j] ) break;
        else { heap[i] = heap[j]; i = j; j = 2*j+1; }
    }
    heap[i] = temp;
}
template <class Type> int MinHeap<Type>::Insert ( const Type &x ) 
{
    //在堆中插入新元素 x
    if ( CurrentSize == MaxHeapSize ) //堆满
    { 
        cout << "堆已满" << endl; return 0; 
    }
    heap[CurrentSize] = x; //插在表尾 
    FilterUp (CurrentSize); //向上调整为堆
    CurrentSize++; //堆元素增一
    return 1;
}
template <class Type> void MinHeap<Type>::FilterUp ( int start ) 
{
    //从 start 开始,向上直到0,调整堆
    int j = start, i = (j-1)/2; // i 是 j 的双亲
    Type temp = heap[j];
    while ( j > 0 ) { 
        if ( (heap[i].root->data.key )<= (temp.root->data.key) ) break;
        else { heap[j] = heap[i]; j = i; i = (i -1)/2; }
    }
    heap[j] = temp;
}
template <class Type> int MinHeap <Type>::RemoveMin ( Type &x ) 
{
    if ( !CurrentSize )
    { 
        cout << "堆已空 " << endl; 
        return 0; 
    }
    x = heap[0]; //最小元素出队列
    heap[0] = heap[CurrentSize-1]; 
    CurrentSize--; //用最小元素填补
    FilterDown ( 0, CurrentSize-1 );
    //从0号位置开始自顶向下调整为堆
    return 1;
}    
#endif

性能测试程序:
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstdlib>
#include <ctime>
#include<iostream>
using std::cout;
using std::cin;
using std::ios;
using std::cerr;
using std::endl;
#include<iomanip>
using std::setw;
using std::fixed;
#include<fstream>
using std::ifstream;
using std::ofstream;
using std::flush;
#include<string>
using std::string;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include"minheap.h"
void BubbleSort(int arr[], int size);//冒泡排序
void QuickSort( int A[], int startingsub, int endingsub);//快速排序
void InsertionSort ( int L[], const int begin,const int n);//插入排序
void Shellsort( int L[], const int left, const int right);//希尔排序
void CountingSort( int L[], const int n );//计数排序
int getDigit(int num, int dig);//基数排序中获取第dig位的数字
void RadixSort(int L[], int left, int right, int d);//基数排序
void printArray( const int Array[], const int arraySize );//输出数组
int main()
{
    clock_t start, finish;
    double duration;
    /* 测量一个事件持续的时间*/
    ofstream *ofs;
    string fileName = "sortResult.txt";
    ofs = new ofstream(fileName.c_str(),ios::out|ios::app);
    const int size = 100000;
    int a[size];
    int b[size];
    srand(time(0));
    ofs->close();
    for(int i = 0; i < 20;i++)
    {
        ofs->open(fileName.c_str(),ios::out|ios::app);
        if( ofs->fail()){
                cout<<"!!";
                ofs->close();
        }
        for(int k =0; k <size;k++)
        {
            a[k] = rand()%1000;
            b[k] = a[k];
            
        }         
        /*    for( k =0; k <size;k++)
        {
        a[k] = k;
        b[k] = a[k];
        
    } */
        //printArray(a,size);    
        //计数排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
        }
        start = clock();
        CountingSort(a,size);
        
        finish = clock();
        //    printArray(a,size);
        
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "计数排序:",duration );
        *ofs<<"第"<<i<<"次:n " <<"排序内容:0~999共" << size << " 个整数n" ;
        *ofs<<"第"<<i<<"次计数排序:n " <<"        Time:    " <<fixed<< duration << " secondsn";
        //基数排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
        }
        start = clock();
        RadixSort(a, 0,size-1, 3);
        finish = clock();
        //    printArray(a,size);
        
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "基数排序:",duration );
        *ofs<<"第"<<i<<"次基数排序:n " <<"        Time:    " << duration << " secondsn";
        //堆排序
        MinHeap<int> mhp(a,size); 
        start = clock();
        for( k =0; k <size;k++)
        {
            mhp.RemoveMin(a[k]);
        }
        finish = clock();
        //    printArray(a,size);
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "堆排序:",duration );
        *ofs<<"第"<<i<<"次堆排序:n " <<"        Time:    " << duration << " secondsn";
        //快速排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
            
        }
        //printArray(a,size);
        start = clock();
        QuickSort(a,0,size-1);
        finish = clock();
        //    printArray(a,size);
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "快速排序:",duration );
        *ofs<<"第"<<i<<"次快速排序:n " <<"        Time:    " << duration << " secondsn";
        //希尔排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
        }
        start = clock();
        Shellsort(a,0,size-1);
        
        finish = clock();
        //    printArray(a,size);
        
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "希尔排序:",duration );
        *ofs<<"第"<<i<<"次希尔排序:n " <<"        Time:    " << duration << " secondsn";
        
        //插入排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
        }
        start = clock();
        InsertionSort (a,0,size-1);
        finish = clock();
        //    printArray(a,size);
        
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "插入排序:",duration );
        *ofs<<"第"<<i<<"次插入排序:n " <<"        Time:    " << duration << " secondsn";
        //冒泡排序
        for( k =0; k <size;k++)
        {
            a[k] =     b[k];
        }
        start = clock();
        BubbleSort(a,size);
        finish = clock();
        //    printArray(a,size);
        
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        printf( "%s%f secondsn", "冒泡排序:",duration );
        *ofs<<"第"<<i<<"次冒泡排序:n " <<"        Time:    " << duration << " secondsn";
        ofs->close();
        }
        return 0;
}
void printArray( const int Array[], const int arraySize )
{
    for( int i = 0; i < arraySize; i++ ) {
        cout << Array[ i ] << " ";
        if ( i % 20 == 19 )
            cout << endl;
    }
    cout << endl;
}

性能仿真:
(排序内容:从0~999中随机产生,共100000 个整数,该表中单位为秒)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值