您的位置:首页 > 编程语言 > C语言/C++

各种排序算法代码C++版

2011-03-15 16:54 405 查看
之前的博文中已经实现了堆排序,因此这里就不做包含

Sort.h

template<typename T>
void exchange(T a,T b){
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
//插入排序
template<typename T>
T* InsertSort(T arr[],int length){
T* tmp=new T[length];
for(int i=0;i<length;i++)
tmp[i]=arr[i];
for(int i=1;i<length;i++){
T p=tmp[i];
int j=i-1;
while((j>=0)&&(tmp[j]>p)){
tmp[j+1]=tmp[j];
j--;
}
tmp[j+1]=p;
}
return tmp;
}

//冒泡排序
template<typename T>
T* BubbleSort(T arr[],int length){
T* tmp=new T[length];
for(int i=0;i<length;i++)
tmp[i]=arr[i];
bool NoSwap;                                 //用来判断是否需要进行交换
for(int i=1;i<length;i++){
NoSwap=true;
for(int j=length-1;j>=i;j--){
if(tmp[j]<tmp[j-1]){
exchange(&tmp[j],&tmp[j-1]);
NoSwap=false;
}
}
if(NoSwap)
break;
}
return tmp;
}

//选择排序
template<typename T>
T* SelectSort(T arr[],int length){
T* tmp=new T[length];
for(int i=0;i<length;i++)
tmp[i]=arr[i];
for(int i=0;i<length;i++){
int smallest=i;
for(int j=i+1;j<length;j++){
if(tmp[smallest]>tmp[j]){
smallest=j;
}
}
if(i!=smallest)
exchange(&tmp[i],&tmp[smallest]);
}
return tmp;
}

//Shell排序
template<typename T>
T* ShellSort(T arr[],int length){
T* tmp=new T[length];
for(int i=0;i<length;i++)
tmp[i]=arr[i];
for(int delta=length/2;delta>0;delta/=2){
for(int j=0;j<delta;j++){
ModifiedInsertSort(&tmp[j],length-j,delta);
}
}
return tmp;
}

template<typename T>
void ModifiedInsertSort(T arr[],int length,int delta){
for(int i=delta;i<length;i+=delta)
for(int j=i;j>=delta;j-=delta){
if(arr[j]<arr[j-delta])
exchange(&arr[j],&arr[j-delta]);
else
break;
}
}

//快速排序
template<typename T>
void QuickSort(T arr[],int left,int right){
if(right<=left)
return;
int Pivot=SelectPivot(left,right);
exchange(&arr[Pivot],&arr[right]);
Pivot=Partition(arr,left,right);
QuickSort(arr,left,Pivot-1);
QuickSort(arr,Pivot+1,right);
}

//template<typename T>
int SelectPivot(int left,int right){
return (left+right)/2;
}

template<typename T>
int Partition(T arr[],int left,int right){
T temp;
int i=left;
int j=right;
temp=arr[j];
while(i!=j){
while((arr[i]<temp)&&(j>i))     //此处的j>i不能漏掉,否则最后可能出现j<i
i++;
if(i<j){                         //避免i,j重合时候还做赋值操作并减少j
arr[j]=arr[i];
j--;
}
while((arr[j]>temp)&&(j>i))     //此处的j>i不能漏掉,否则最后可能出现j<i
j--;
if(i<j){                        //避免i,j重合时候还做赋值操作并增加i
arr[i]=arr[j];
i++;
}
}
arr[i]=temp;
return i;
}

//归并排序
template<typename T>
void MergeSort(T arr[],/*T tmp[],*/int left,int right){
if(left<right)
{
int middle=(left+right)/2;
MergeSort(arr,/*tmp,*/left,middle);
MergeSort(arr,/*tmp,*/middle+1,right);
Merge(arr,/*tmp,*/left,middle,right);
}
}

template<typename T>
void Merge(T arr[],/*T tmp[],*/int left,int middle,int right){
T* tmp=new T[right-left+1];
for(int i=left;i<=right;i++)
tmp[i]=arr[i];
int index1=left;
int index2=middle+1;
int i=left;
while((index1<=middle)&&(index2<=right)){
if(tmp[index1]<=tmp[index2])
arr[i++]=tmp[index1++];
else
arr[i++]=tmp[index2++];
}
while(index1<=middle)
arr[i++]=tmp[index1++];
while(index2<=right)
arr[i++]=tmp[index2++];
}

//堆排序
//见前面文章

//桶式排序
template<typename T>
void BucketSort(T arr[],int length,int max){
//arr为待排序数组,数组长度为n,所有记录都位于[0,max)上,有负数的话要做另外的处理
T *tmp=new T[length];                                //临时数组用来保存arr的信息
for(int i=0;i<length;i++)
tmp[i]=arr[i];
int* count=new int[max];                             //小于或等于元素i的个数
for(int i=0;i<max;i++)
count[i]=0;
//统计每个取值出现的次数
for(int i=0;i<length;i++)
count[arr[i]]++;
//统计小于等于i的次数
for(int i=1;i<max;i++)
count[i]+=count[i-1];
//从尾部开始按顺序输出有序序列,保证排序的稳定性
for(int i=length-1;i>=0;i--)
arr[--count[tmp[i]]]=tmp[i];
}

//基数排序
template<typename T>
void RadixSort(T arr[],int length,int d,int r){
//d为排序码个数,r为基数
T* tmp=new T[length];
int *count=new int[r];
int i,j,k;
/*
for(i=0;i<length;i++)
tmp[i]=arr[i];
*/
int Radix=1;
//定义的变量有点多,i,j,k要注意它们的作用域,一开始我在外层循环用了i,然后不小心里面又用了i结果程序出现错误
for(i=1;i<=d;i++){
for(j=0;j<length;j++)
tmp[j]=arr[j];
for(j=0;j<r;j++)
count[j]=0;
for(j=0;j<length;j++){
k=(tmp[j]/Radix)%r;
count[k]++;
}
for(j=1;j<r;j++)
count[j]+=count[j-1];
for(j=length-1;j>=0;j--){
k=(tmp[j]/Radix)%r;
count[k]--;
arr[count[k]]=tmp[j];
}
Radix*=r;
}

}


测试代码

#include "Sort.h"
#include<iostream>
using namespace std;

int main(){
int a[]={45,34,78,12,34,32,29,64};
cout<<"Before insertsort: "<<endl;
for(int i=0;i<8;i++)
cout<<a[i]<<" ";
cout<<endl;
int* b=InsertSort(a,8);
cout<<"After insertsort: "<<endl;
for(int i=0;i<8;i++)
cout<<b[i]<<" ";
cout<<endl;
int* c=BubbleSort(a,8);
cout<<"After bubblesort: "<<endl;
for(int i=0;i<8;i++)
cout<<c[i]<<" ";
cout<<endl;
int* d=SelectSort(a,8);
cout<<"After selectsort: "<<endl;
for(int i=0;i<8;i++)
cout<<d[i]<<" ";
cout<<endl;
int* e=ShellSort(a,8);
cout<<"After shellsort: "<<endl;
for(int i=0;i<8;i++)
cout<<e[i]<<" ";
cout<<endl;
int* f=new int[8];
for(int i=0;i<8;i++)
f[i]=a[i];
QuickSort(f,0,7);
cout<<"After quicksort: "<<endl;
for(int i=0;i<8;i++)
cout<<f[i]<<" ";
cout<<endl;
int* g=new int[8];
for(int i=0;i<8;i++)
g[i]=a[i];
MergeSort(g,0,7);
cout<<"After mergesort: "<<endl;
for(int i=0;i<8;i++)
cout<<g[i]<<" ";
cout<<endl;
int* h=new int[8];
for(int i=0;i<8;i++)
h[i]=a[i];
BucketSort(h,8,79);
cout<<"After bucketsort: "<<endl;
for(int i=0;i<8;i++)
cout<<h[i]<<" ";
cout<<endl;
int* j=new int[8];
for(int i=0;i<8;i++)
j[i]=a[i];
RadixSort(j,8,2,10);
cout<<"After radixsort: "<<endl;
for(int i=0;i<8;i++)
cout<<j[i]<<" ";
cout<<endl;
system("PAUSE");
return 0;
}


各种算法时间空间复杂度及稳定性比较:

插入排序

时间:n2 空间:1 稳定

冒泡排序

时间:n2 空间:1 稳定

选择排序

时间:n2 空间:1 不稳定

shell排序

时间:n3/2 空间:1 不稳定

快速排序

时间:nlogn 空间:logn 不稳定

归并排序

时间:nlogn 空间:n 稳定

堆排序

时间:nlogn 空间:1 不稳定

桶式排序

时间:n+m 空间:n+m 稳定

基数排序

时间d(n+r) 空间:n+r 稳定

注:n为排序的数组长度,m为元素的最大值,r为基数,d为排序的元素的位数;稳定的排序指的是排序前后,相同元素的相对位置不变
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: