各种排序算法代码C++版
2011-03-15 16:54
405 查看
之前的博文中已经实现了堆排序,因此这里就不做包含
Sort.h
测试代码
各种算法时间空间复杂度及稳定性比较:
插入排序
时间: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为排序的元素的位数;稳定的排序指的是排序前后,相同元素的相对位置不变
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为排序的元素的位数;稳定的排序指的是排序前后,相同元素的相对位置不变
相关文章推荐
- 各种排序算法的c++代码实现
- c++代码实现各种排序算法
- 【算法】各种排序算法测试代码
- 各种排序算法的C++实现与性能比较
- 【排序算法】用C++实现各种排序算法
- 各种排序算法代码汇总
- 各种排序算法总结及C#代码实现
- Python实现各种排序算法的代码示例总结
- 各种排序算法的实现及其比较(c++实现)
- 各种排序算法代码(C语言版)
- 各种排序算法的实现代码
- 各种排序算法的代码
- C++各种排序算法
- 【Algorithm】c++实现各种排序算法
- java的各种排序算法代码整理
- python实现的各种排序算法代码
- 【面试必看】各种排序算法代码实现
- 使用c++实现并分析各种排序算法
- C/C++ 排序算法大全代码
- Python实现各种排序算法的代码示例总结