C++排序算法总结
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(3)冒泡排序(稳定) template <class T> void bubsort(T s,size_t len){
for(int i=0;i<len-1;++i){//loop count int op=0; for(int m=0;m<len-i;++m){ if(s[m]>s[m+1]){ int tmp=s[m]; s[m]=s[m+1]; s[m+1]=tmp; op=1; } } if(!op)return;
--sub; continue; } swap(heap[sub-1],heap[csub-1]); --sub; } } template <class T> void hsort(T heap,size_t s){ while(s>1){ hadjust<T>(heap,s); swap(heap[0],heap[s-1]); --s; } } int main(void){ int buf[]={17,3,15,2,4,9,3,12,1,6,8,12};
int pi[]={34,23,53,66,73,81,13,22,5,98,92,2,35,6,78,81,51,20,63,55,31,61, 90,27,77};
int l=sizeof(pi)/sizeof(int); #define PUSH(b,v) buk[b][++t[b]]=v for(size_t i=0;i<l;++i){//low demical
if(value<*mid)return bsearch(value,begin,mid);
else
return
bsearch(value,++mid,end);
}
return -1;
}
int main(void){
int buf2[]={1,3,9,10};
int idx=bsearch<int,int*>(1,buf2,&buf2[3]);
int hvb=pi[i]%10; PUSH(hvb,pi[i]); } p=pi; getall(); copy(&pi[0],&pi[l],ostream_iterator<int>(cout," ")); printf("\n"); for(int st=0;st<DEMICAL;++st){t[st]=0;} for(size_t i=0;i<l;++i){//high demical int hvb=pi[i]/10; PUSH(hvb,pi[i]); } p=pi; getall(); copy(&pi[0],&pi[l],ostream_iterator<int>(cout," ")); printf("\n"); return 0; }
template <class C>
int bsearch(C value,iterator begin,iterator end){
iterator mid=& begin[(end-begin)/2];
if(*mid==value)return begin-mid;
else{
if(begin==end)return -1;
2
#define DEMICAL 10 int buk[DEMICAL][DEMICAL+1];//bucket short t[DEMICAL];//top; int *p; void getb(size_t b){ printf("\nt[b]=%d,",t[b]); if(t[b]==0){
T v=*b; if(*n<v){
*n^=*b;
4
*b^=*n; *n^=*b; op=true; } ++n; } if(op==false)return; } }
(7)快速排序(不稳定)----如果您的实现比我的更简短,欢迎对比:) /*用法
int buf[]={17,3,15,2,4,9,3,12,1,6}; qsort(&buf[0],&buf[10]); copy(&buf[0],&buf[10],ostream_iterator<int>(cout," ")); */ #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template <class T> void qsort(T begin,T end){
T* left=&begin[i*gs]; T* mid =&begin[i*gs+gs]; if(i==group-1)mid=end;//always process end element mergesort<T*>(left,mid,end);//由于两部分已经有序,因此可以使用 mergeList 方法 来实现合并 } ss<<=1; } } 归并的递归实现 void merge(T* begin,T*end){ int* mid=(int*)( ( (int)begin+(int)end )/2 ); if(begin!=mid)merge(begin,mid); if(mid!=end) merge(++mid,end); mergesort<T*>(begin,mid,end);//实现方法同上 }
5
for(int g=sqr(s);g>1;g=sqr(g)){/A/分组 size_t gs=s/g;//gs 是 group size for(int n=0;n<gs;++n){//每次分组以后,处理某个组里面全部的元素 isort(begin+n*g, g, g); }//每个组的所有元素 if(gs*g<s)isort(begin+gs*g,g,s-gs*g);//末尾剩余的元素
} }
(4)基数排序:O(nlog(r)m)其中 r 为所采取的基数,而 logr(n)=m 为堆数,在某 些时候,基数排序法的效率高于其它的比较性排序法。合理设计 r 和 m 的值,可 以得到最有解。它利用了每次比较以后得到的历史信息。需要根据需求具体设计, 没有通用形式,必须根据具体问题的信息具体设计,例如扑克牌排序等。它的核 心思想是利用数据的某方面的特定信息。下面的例子是排序如果各 2 位正数,使 用了 10 个桶 #include<cstdio> #include<cstdlib> #include<algorithm> #include<iterator> #include<iostream> //Radix,Bucket sort
printf("buk[%d] is empty",b); return; }else{ for(int i=1;i<=t[b];++i){
printf("buk[%d,%d]=%d ",b,i,buk[b][i]); *p++=buk[b][i]; } } } void getall(){for(int a=0;a<DEMICAL;++a){getb(a);} printf("\n");} int main(int argc, char *argv[]) {
if(idx!=-1)printf("v=%d,pos=%d\n",buf2[idx],idx);
else printf("not found\n");
return 0;
}
(2)插入排序(稳定)----当然,可以用折半插入排序来提高性能
template <class T>
void isort(T begin,size_t length){
(6)直接选择排序(不稳定) /*用法
int buf[]={7,3,5,2,4,9,3,12,1,6}; csort(buf,&buf[10]); */ template <class T> void csort(T* begin,T* end){ for(T* b=begin;b!=end;++b){ T* n=b; ++n; bool op=false; while(n!=end){
s[c+k]=s
[c+k-1];
1
} break; } } s[c]=begin[b]; } memcpy(begin,s,l); delete[] s; } main(...) short buf2[]={11,3,9,10,7,6,15,2}; isort(buf2,8); for(int i=0;i<sizeof(buf2)/sizeof(short);++i)printf("%d ",buf2[i]);
size_t sub=len/2;//不大于 n/2 的整数 while(sub){
size_t left =sub<<1; size_t right=left+1; int csub;//需要交换的子节点 if(right>len)csub=left; else csub=heap[left-1]>heap[right-1]?left:right; if(heap[sub-1]>=heap[csub-1]){
T left=begin; if(++left>=end)return;//只有一个元素了 size_t m= ( (size_t)end-(size_t)begin )/(2*sizeof(T));//STL 里面这个中间位置是怎么计算的? int*并没有 distace 和 advance 这样对应的迭代方法... ... T mid=&begin[m]; swap(*begin,*mid); T last=left; for(;left!=end;++left){
3
(5)归并排序 template <class T> void merge(T* begin,T* end,size_t len){
int es=sizeof(*begin);//元素大小 int ss=1;//sub size;//组内元素个数 while(ss<len){
int gs=ss<<1; int group=len/gs+len%gs;//分组个数 if(gs>group)group=1; printf("gsize=%d,group=%d,ss=%d===========\n",gs,group,ss); for(int i=0;i<group;++i){
if(*begin>*left){//找到了更小Βιβλιοθήκη Baidu数 if(left!=last){ swap(*left,*last); } ++last;
} } qsort(begin,last); qsort(last,end); }
(8)希尔排序(不稳定) 可以理解为直接插入排序的变体。这里只给出伪代码: 首先实现一个直接插入排序 void isort(*begin,size_t offset,size_t number); 这里 offset 是插入排序的间隔,number 是插入排序的元素个数 void shellsort(T begin,T end,size_t s){
(1)2 分法查找
(2)插入排序(稳定)
(3)冒泡排序(稳定)
(4)基数排序
(5)归并排序
(6)直接选择排序(不稳定)
(7)快速排序(不稳定)
(8)希尔排序(不稳定)
(9)堆排序
=================================================
(1)2 分法查找有序连续内存
}//若干个组 }
(9)最后隆重推出百万级俱乐部成员: 堆排序。程序模板在 gcc3.4.2 下验证通过 #include<cstdio> #include<cstdlib> #include<cstdio> #include<iostream> #include<iterator> using namespace std; #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template <class T> void hadjust(T heap,size_t len){
size_t l=length*sizeof(*begin);
T
s=(T)malloc(l);
s[0]=begin[0];
for(int b=1;b<length;++b){
size_t c=0;
for(;c<b;++c){
if(begin[b]<s[c]){
for(size_t
k=b-c;k>0;--k){
for(int i=0;i<len-1;++i){//loop count int op=0; for(int m=0;m<len-i;++m){ if(s[m]>s[m+1]){ int tmp=s[m]; s[m]=s[m+1]; s[m+1]=tmp; op=1; } } if(!op)return;
--sub; continue; } swap(heap[sub-1],heap[csub-1]); --sub; } } template <class T> void hsort(T heap,size_t s){ while(s>1){ hadjust<T>(heap,s); swap(heap[0],heap[s-1]); --s; } } int main(void){ int buf[]={17,3,15,2,4,9,3,12,1,6,8,12};
int pi[]={34,23,53,66,73,81,13,22,5,98,92,2,35,6,78,81,51,20,63,55,31,61, 90,27,77};
int l=sizeof(pi)/sizeof(int); #define PUSH(b,v) buk[b][++t[b]]=v for(size_t i=0;i<l;++i){//low demical
if(value<*mid)return bsearch(value,begin,mid);
else
return
bsearch(value,++mid,end);
}
return -1;
}
int main(void){
int buf2[]={1,3,9,10};
int idx=bsearch<int,int*>(1,buf2,&buf2[3]);
int hvb=pi[i]%10; PUSH(hvb,pi[i]); } p=pi; getall(); copy(&pi[0],&pi[l],ostream_iterator<int>(cout," ")); printf("\n"); for(int st=0;st<DEMICAL;++st){t[st]=0;} for(size_t i=0;i<l;++i){//high demical int hvb=pi[i]/10; PUSH(hvb,pi[i]); } p=pi; getall(); copy(&pi[0],&pi[l],ostream_iterator<int>(cout," ")); printf("\n"); return 0; }
template <class C>
int bsearch(C value,iterator begin,iterator end){
iterator mid=& begin[(end-begin)/2];
if(*mid==value)return begin-mid;
else{
if(begin==end)return -1;
2
#define DEMICAL 10 int buk[DEMICAL][DEMICAL+1];//bucket short t[DEMICAL];//top; int *p; void getb(size_t b){ printf("\nt[b]=%d,",t[b]); if(t[b]==0){
T v=*b; if(*n<v){
*n^=*b;
4
*b^=*n; *n^=*b; op=true; } ++n; } if(op==false)return; } }
(7)快速排序(不稳定)----如果您的实现比我的更简短,欢迎对比:) /*用法
int buf[]={17,3,15,2,4,9,3,12,1,6}; qsort(&buf[0],&buf[10]); copy(&buf[0],&buf[10],ostream_iterator<int>(cout," ")); */ #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template <class T> void qsort(T begin,T end){
T* left=&begin[i*gs]; T* mid =&begin[i*gs+gs]; if(i==group-1)mid=end;//always process end element mergesort<T*>(left,mid,end);//由于两部分已经有序,因此可以使用 mergeList 方法 来实现合并 } ss<<=1; } } 归并的递归实现 void merge(T* begin,T*end){ int* mid=(int*)( ( (int)begin+(int)end )/2 ); if(begin!=mid)merge(begin,mid); if(mid!=end) merge(++mid,end); mergesort<T*>(begin,mid,end);//实现方法同上 }
5
for(int g=sqr(s);g>1;g=sqr(g)){/A/分组 size_t gs=s/g;//gs 是 group size for(int n=0;n<gs;++n){//每次分组以后,处理某个组里面全部的元素 isort(begin+n*g, g, g); }//每个组的所有元素 if(gs*g<s)isort(begin+gs*g,g,s-gs*g);//末尾剩余的元素
} }
(4)基数排序:O(nlog(r)m)其中 r 为所采取的基数,而 logr(n)=m 为堆数,在某 些时候,基数排序法的效率高于其它的比较性排序法。合理设计 r 和 m 的值,可 以得到最有解。它利用了每次比较以后得到的历史信息。需要根据需求具体设计, 没有通用形式,必须根据具体问题的信息具体设计,例如扑克牌排序等。它的核 心思想是利用数据的某方面的特定信息。下面的例子是排序如果各 2 位正数,使 用了 10 个桶 #include<cstdio> #include<cstdlib> #include<algorithm> #include<iterator> #include<iostream> //Radix,Bucket sort
printf("buk[%d] is empty",b); return; }else{ for(int i=1;i<=t[b];++i){
printf("buk[%d,%d]=%d ",b,i,buk[b][i]); *p++=buk[b][i]; } } } void getall(){for(int a=0;a<DEMICAL;++a){getb(a);} printf("\n");} int main(int argc, char *argv[]) {
if(idx!=-1)printf("v=%d,pos=%d\n",buf2[idx],idx);
else printf("not found\n");
return 0;
}
(2)插入排序(稳定)----当然,可以用折半插入排序来提高性能
template <class T>
void isort(T begin,size_t length){
(6)直接选择排序(不稳定) /*用法
int buf[]={7,3,5,2,4,9,3,12,1,6}; csort(buf,&buf[10]); */ template <class T> void csort(T* begin,T* end){ for(T* b=begin;b!=end;++b){ T* n=b; ++n; bool op=false; while(n!=end){
s[c+k]=s
[c+k-1];
1
} break; } } s[c]=begin[b]; } memcpy(begin,s,l); delete[] s; } main(...) short buf2[]={11,3,9,10,7,6,15,2}; isort(buf2,8); for(int i=0;i<sizeof(buf2)/sizeof(short);++i)printf("%d ",buf2[i]);
size_t sub=len/2;//不大于 n/2 的整数 while(sub){
size_t left =sub<<1; size_t right=left+1; int csub;//需要交换的子节点 if(right>len)csub=left; else csub=heap[left-1]>heap[right-1]?left:right; if(heap[sub-1]>=heap[csub-1]){
T left=begin; if(++left>=end)return;//只有一个元素了 size_t m= ( (size_t)end-(size_t)begin )/(2*sizeof(T));//STL 里面这个中间位置是怎么计算的? int*并没有 distace 和 advance 这样对应的迭代方法... ... T mid=&begin[m]; swap(*begin,*mid); T last=left; for(;left!=end;++left){
3
(5)归并排序 template <class T> void merge(T* begin,T* end,size_t len){
int es=sizeof(*begin);//元素大小 int ss=1;//sub size;//组内元素个数 while(ss<len){
int gs=ss<<1; int group=len/gs+len%gs;//分组个数 if(gs>group)group=1; printf("gsize=%d,group=%d,ss=%d===========\n",gs,group,ss); for(int i=0;i<group;++i){
if(*begin>*left){//找到了更小Βιβλιοθήκη Baidu数 if(left!=last){ swap(*left,*last); } ++last;
} } qsort(begin,last); qsort(last,end); }
(8)希尔排序(不稳定) 可以理解为直接插入排序的变体。这里只给出伪代码: 首先实现一个直接插入排序 void isort(*begin,size_t offset,size_t number); 这里 offset 是插入排序的间隔,number 是插入排序的元素个数 void shellsort(T begin,T end,size_t s){
(1)2 分法查找
(2)插入排序(稳定)
(3)冒泡排序(稳定)
(4)基数排序
(5)归并排序
(6)直接选择排序(不稳定)
(7)快速排序(不稳定)
(8)希尔排序(不稳定)
(9)堆排序
=================================================
(1)2 分法查找有序连续内存
}//若干个组 }
(9)最后隆重推出百万级俱乐部成员: 堆排序。程序模板在 gcc3.4.2 下验证通过 #include<cstdio> #include<cstdlib> #include<cstdio> #include<iostream> #include<iterator> using namespace std; #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template <class T> void hadjust(T heap,size_t len){
size_t l=length*sizeof(*begin);
T
s=(T)malloc(l);
s[0]=begin[0];
for(int b=1;b<length;++b){
size_t c=0;
for(;c<b;++c){
if(begin[b]<s[c]){
for(size_t
k=b-c;k>0;--k){