简洁的排序算法实现

插入排序 Insert Sort

template <class Elem,class Comp>
void inssort(Elem A[],int n){
  for (int i = 1; i < n; i++)
    for (int j = i; (j > 0)&&(Comp::lt(A[j],A[j-1])); j--)
        swap(A,j,j-1);
}

冒泡排序 Bubble Sort

template <class Elem,class Comp>
void bubsort(Elem A[],int n){
  for (int i = 0; i < n-1; i++)
    for (int j = n-1; j > i; j--)
      if (Comp::lt(A[j],A[j-1]))
        swap(A,j,j-1);
}

选择排序 Selection Sort

template <class Elem,class Comp>
void selsort(Elem A[],int n){
    for (int i = 0; i < n-1; ++i){
        int lowindex = i;
        for (int j = n-1; j > i ; j--)
            if (Comp::lt(A[j],A[lowindex]))
                lowindex = j;
        swap(A,i,lowindex);          
    }
}

希尔排序 Shellsort

template <class Elem,class Comp>
void inssort2(Elem A[],int n,int incr){
  for (int i = incr ; i < n; i+=incr)
    for (int j = i; (j >= incr)&&Comp::lt(A[j],A[j-incr]); j-=incr)
      swap(A,j,j-incr);
}
template <class Elem,class Comp>
void shellsort(Elem A[],int n){
  for (int i = n/2; i >= 2; i/=2)
    for (int j = 0; j < i; ++j)
      inssort2<Elem,Comp>(&A[j],n,i);
  inssort2<Elem,Comp>(A,n,1);
}

快速排序 Quicksort

//Here is a simple implement of findpivot,but it is better to pick a value at random
template <class Elem>
int findpivot(Elem A[],int i,int j){
  return (i+j)/2;
}

template <class Elem,class Comp>
void partition(Elem A[],int l,int r,Elem& pivot){
  do{
    while(Comp::lt(A[++l],pivot));
    while((r!=0)&&Comp::gt(A[--r],pivot));
    swap(A,l,r);
  }while(l<r);
  swap(A,l,r);//Reverse last,wasted swap
  return l;
}

template <class Elem,class Comp>
void quicksort(Elem A[],int i,int j){
  if(j <= i) return;// Don't sort 0 or 1 Elem
  int pivotindex = findpivot(A,i,j);
  swap(A,pivotindex,j);
  int k = partition(A,i-1,j,A[j]);
  swap(A,k,j);
  quicksort<Elem,Comp>(A,i,k-1);
  quicksort<Elem,Comp>(A,k+1,j);
}
以上为书中源码,下面为本人胆大妄为,略微改进后的代码
template <class Elem,class Comp>
void partition(Elem A[],int l,int r,Elem pivot){
  do{
    while(l<r&&Comp::lt(A[l],pivot)) l++;
    A[r] = A[l];
    while(l<r&&Comp::gt(A[r],pivot) r--;
    A[l] = A[r];
  }while(l<r);
  return l;
}

template <class Elem,class Comp>
void quicksort(Elem A[],int i,int j){
  if(j <= i) return;// Don't sort 0 or 1 Elem
  int pivotindex = findpivot(A,i,j);
  Elem pivot = A[pivotindex];//save pivot 
  swap(A,pivotindex,j);
  int k = partition(A,i,j,pivot);
  A[k] = pivot;
  quicksort<Elem,Comp>(A,i,k-1);
  quicksort<Elem,Comp>(A,k+1,j);
}
减少了交换函数中的中间变量的开支

归并排序 Mergesort

template <class Elem,class Comp>
void mergesort(Elem A[],Elem temp[],int left,int right,int minsortlen){
    if(left == right) return;
    //use Insertion Sort to sort small subarrays
    if((right-left) <= minsortlen){
        inssort<Elem,Comp>(&A[left],right-left+1);
        return;
    }
    int i,j,k,mid = (left+right)/2;
    mergesort<Elem,Comp>(A,temp,left,mid,minsortlen);
    mergesort<Elem,Comp>(A,temp,mid+1,right,minsortlen);
    for (i = mid; i >= left; i--)
        temp[i]=A[i];
    for (j = 1; j <= right-mid; j++)
        temp[right-j+1] = A[j+mid];
    for (i = left,j = right,k = left;k<=right;k++)
        if (temp[i] < temp[j]) 
            A[k] = temp[i++];
        else
            A[k] = temp[j--];

}

基数排序 Radix Sort

template <class Elem,class Comp>
//cnt[i] stores number of records in bin[i]
void radix(Elem A[],Elem B[],int r,int n,int k,int cnt[]){
    int j;
    for (int i = 0,rtok = 1; i < k; ++i,rtok*=r){
        for (j = 0;j < r;j++)
            cnt[j] = 0;
        //Count the number of records for each bin on this pass
        for (j = 0;j < n;j++)
            cnt[(A[j]/rtok)%r]++;
        //cnt[j] will be index for last slot of bin j
        for (j = 1;j < r;j++)
            cnt[j] = cnt[j] + cnt[j-1];
        for (j = n-1;j >= 0;j--)
            B[--cnt[(A[j]/rtok)%r]] = A[j];
        for (j = 0;j < n;j++)
            A[j] = B[j];
    }
}

Appendix Utility Functions

template <class Elem,class Comp>
inline void swap(Elem A[],int i,int j){
  Elem t = A[i];
  A[i] = A[j];
  A[j] = t;
}

参考书籍:数据结构与算法分析(c++版)(第二版)(作者:Clifford A.Shaffer)


有错误的地方望指出,谢谢!


持续更新


欢迎转载,但请附上原地址http://blog.csdn.net/jiaxingzheng/article/details/48713911,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值