各种排序比较




#include <iostream>
using namespace std;

typedef const int& itemType ;

typedef bool (*cmp)( itemType a, itemType b);

bool myless(const int& a,const int& b)
{
    return a<b;
}


template <class T>
void myswap(T& a,T& b)
{
    if ( a!=b ){
        a = a+b;
        b = a-b;
        a = a-b;
    }
}

/**
 * 名称:选择排序
 * 功能:对数据进行排序
 * 时间复杂度:O(n2)
 * 是否稳定:是
 * 与输入序列有关:否
 * 特点:
     a:比较次数:n(n-1)/2
     b:交换次数:0(最少),n(最多)
    适用于交换代价较高,而比较代价较小的数据量不大的排序中.
**/ 
template <class T>
void select_sort(T *a,const int le,const int ri,cmp compare=myless)
{
    for ( int i=le; i<ri ; ++i ){
        int minPos = i;
        for ( int j=i+1; j<ri; ++j ){
            if ( compare(a[j],a[minPos]) ){
                minPos = j;
            }
        }
        myswap(a[i],a[minPos]);
    }
}

/**
 * 名称:冒泡排序
 * 功能:对数据进行排序
 * 时间复杂度: O(n2)
 * 是否稳定:是
 * 与输入序列是否有关:有
**/ 
template <class T>
void bubble_sort(T *a,const int le,const int ri,cmp compare=myless)
{
    bool flag = true;
    for ( int i=le+1; i<ri &&flag ; ++i ){
        for ( int j=le+1; j<ri-i+le+1; ++j ){
            flag = false;   //添加了这条语句进行判断,才和输入有关.
            if ( myless(a[j],a[j-1]) ){
                myswap(a[j],a[j-1]);
                flag =true;
            }
        }
    }
}

/**
 * 名称:插入排序
 * 功能:对数据进行排序
 * 时间复杂度:O(n2)
 * 是否稳定:是
 * 是否与输入有关: 是
**/ 
template <class T>
void insert_sort(T *a,const int le,const int ri,cmp compare=myless)
{
    for ( int i=le+1; i<ri;i++ ){
        int j =i;
        while ( j>le && myless(a[j],a[j-1]) ){
            myswap(a[j],a[j-1]);
            --j;
        }
    }
}





/**
 * 名称:计数排序
 * 功能:对数据进行排序
 * 时间复杂度:O(n)
 * 是否稳定:是
 * 是否与输入有关: 否
**/ 
template <class T>
void count_sort(T *a,const int le,const int ri,const int max)
{
    T *b = new T[ri-le+1];
    int *cnt = new int[max+1];
    for ( int i=0; i<max+1;++i ){
        cnt[i]=0;
    }
    for ( int i=le;i<ri;++i ){
        cnt[a[i]]++; 
    }
    for ( int i=1;i<max+1;i++ ){
        cnt[i]+=cnt[i-1];
    }

    for ( int i=ri-1;i>=le;--i ){
        b[cnt[a[i]]--]=a[i];
    }
    for ( int i=le; i<ri ;++i ){
        a[i]=b[i-le+1];
    }

    delete []b;
    delete []cnt;
}

/**
 * 名称:希尔排序
 * 功能:对数据进行排序
 * 时间复杂度:O(n2)
 * 是否稳定:否
 * 与输入序列有关:是
 * 特点:
     这是对插入排序的一种优化(某些时候)
     插入排序步速为1,有时候某一个元素移动n步才回到自己的位置,
     这时候我们希望这种移动次数减少,所以我们尝试加大步速,
     于是我们用shell排序,一开始设置非常大的步速,然后每次减少步速,
     这样每次排序的时候总是有大部分数据已经排好序了.
**/ 
template <class T>
void shell_sort(T* a,const int le,const int ri,cmp compare = myless)
{
    int key[]={1,4,13,40,121,364,1093};
    int key_index=0;
    while ((ri-le)/key[key_index] >=2)//计算最大步速
        ++key_index;
    for ( --key_index ; key_index>=0; --key_index ){ //每次循环步速index-1
        for ( int i = le; i<le +key[key_index]; ++i ){  //分组
            for ( int j =i+key[key_index]; j<ri; j+=key[key_index] ){ //每一组进行插入排序
                int k = j;
                while ( k>i && myless(a[k],a[k-key[key_index]]) ){
                    myswap(a[k],a[k-key[key_index]]);
                    k -=key[key_index];
                }
            }
        }
    }
}


/**
 * 功能:合并两个已排好序的数组
**/ 
template <class T>
void merge(T *a,const int ale,const int ari,
           T *b,const int ble,const int bri,
           T *c,const int cle,const int cri)
{
    int c_index = cle;
    int a_index = ale;
    int b_index = ble;
    while ( c_index<cri && a_index<ari && b_index<bri ){
        c[c_index++] = myless(a[a_index],b[b_index]) ? 
                        a[a_index++]:b[b_index++];
    }
 
    while ( c_index<cri && a_index<ari){
        c[c_index++] = a[a_index++];
    }
    while ( c_index<cri  && b_index<bri){
        c[c_index++] = b[b_index++];
    }
    for ( int i=cle; i<cri; ++i){
        a[i] = c[i];
    }
}

/**
 * 名称:归并排序
 * 时间复杂度:O(nlgn)
 * 空间复杂度:O(n)
**/ 
template <class T>
void merge_sort(T* a,const int ale,const int ari,
                T* c,const int cle,const int cri)
{
    if ( ale+1<ari ){
        int middle = ((ari-ale)>>1)+ale;
    
        merge_sort(a,ale,middle,c,cle,middle);
        merge_sort(a,middle,ari,c,middle,cri);
   
        merge(a,ale,middle,
              a,middle,ari,
              c,ale,ari);
    }
}

/**
 * 保持堆的性质 
**/ 
template <class T>
void keep_heap(T* a, const int beg,const int ed)
{
    int temp = a[beg];
    int start = beg;
    for ( int i=beg*2+1; i<ed; i = i*2+1 ){
        if ( i+1<ed && myless(a[i],a[i+1])  ){
            i++;
        }
        if (  myless(a[i],temp) ){
            break;
        }
        a[start] = a[i];
        start = i;
    }
    a[start] = temp;
}

/**
 * 建堆
**/ 
template <class T>
void built_heap(T* a,const int nSize)
{
    for ( int i=nSize/2 ; i>=0; --i ){
        keep_heap(a,i,nSize);
    }

    /* for ( int i=0 ; i<10; ++i ){
    cout<<a[i]<<" ";
    }*/
}

/**
 * 名称:堆排序
 * 时间复杂度:O(nlgn)
 * 空间复杂度:O(1)
**/ 
template <class T>
void heap_sort(T* a,const int nSize)
{
    built_heap(a,nSize);
    for ( int i = nSize-1; i>0; --i ){
        myswap(a[i],a[0]);
        keep_heap(a,0,i);
    } 
}

/**
 * 获取下标
**/ 
template <class T>
int getPos(T* a,const int le,const int ri)
{
    /*int j=le-1;
    for ( int i=le; i<ri-1; ++i ){
    if ( myless(a[i],a[ri-1]) ){
    myswap(a[++j],a[i]);
    }
    }
    myswap(a[++j],a[ri-1]);
    return j;*/
    int start = le;
    int ed = ri-2;
    while ( start <ed ){
        while ( myless(a[start],a[ri-1]) ){
            ++start;
        }
        while ( ed>=start && myless(a[ri-1],a[ed])  ){
            --ed;
        }
        if ( start < ed ){
            myswap(a[start],a[ed]);
        }
    }
    myswap(a[start],a[ri-1]);
    return start;
}

/**
 * 快速排序 1
 * 时间复杂度:O(nlgn)
 * 空间复杂度:O(lgn)
**/ 
template <class T>
void quick_sort(T* a,const int le,const int ri)
{
    if ( le+1<ri ){
        int pos = getPos(a,le,ri);
        quick_sort(a,le,pos);
        quick_sort(a,pos+1,ri);
    }
}


int main()
{
    int a[]={2,3,4,5,6,7,6,5,3,2};
    int c[10];
    
    //select_sort(a,0,10);
    //shell_sort(a,0,10);
    //bubble_sort(a,0,10);
    //insert_sort(a,0,10);
    //count_sort(a,0,10,7);
    //heap_sort(a,10);
    quick_sort(a,0,10);
    //merge_sort(a,0,10,c,0,10);
    for ( int i=0 ; i<10; ++i ){
        cout<<a[i]<<" ";
    }

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值