插入排序 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)