C++数据结构 排序 二分 插入 冒泡 基数 归并 直选 快排 希尔 堆排序

原文地址:http://hi.baidu.com/sunguangran/blog/item/f972073465c0b347241f1425.html

 

认真的学习了严蔚敏版的数据结构,感觉应该自己实现一下通用的算法才能有更深入的理解,于是贡献给大家下面这些我自己写的,使用C++模版实现了所有常见的排序算法,所有算法都很短小精悍,gcc编译运行通过(希尔排序除外)。
其中快速排序的代码最短小实用(欢迎各位dx拍砖),last监视哨的思想来自百度百科对qsort的解释----它大大简化了qsort的代码量。后续我将测试所有这些算法性能的情况,并对比C/C++库的标准函数。

(1)2分法查找有序连续内存

template 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; 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(1,buf2,&buf2[3]); if(idx!=-1)printf("v=%d,pos=%d/n",buf2[idx],idx); else printf("not found/n"); return 0; }
(2)插入排序(稳定)----当然,可以用折半插入排序来提高性能
 template void isort(T begin,size_t length){ size_t l=length*sizeof(*begin); T s=(T)malloc(l); s[0]=begin[0]; for(int b=1;b0;--k){ s[c+k]=s[c+k-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

(3)冒泡排序(稳定)
template void bubsort(T s,size_t len){ for(int i=0;is[m+1]){ int tmp=s[m]; s[m]=s[m+1]; s[m+1]=tmp; op=1; } } if(!op)return; } }

(4)基数排序:O(nlog(r)m)其中r为所采取的基数,而logr(n)=m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。合理设计r和m的值,可以得到最有解。它利用了每次比较以后得到的历史信息。需要根据需求具体设计,没有通用形式,必须根据具体问题的信息具体设计,例如扑克牌排序等。它的核心思想是利用数据的某方面的特定信息。下面的例子是排序如果各2位正数,使用了10个桶

#include #include #include #include #include //Radix,Bucket sort #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){ 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(cout," ")); printf("/n"); for(int st=0;st(cout," ")); printf("/n"); return 0; }

(5)归并排序
template void merge(T* begin,T* end,size_t len){ int es=sizeof(*begin);//元素大小 int ss=1;//sub size;//组内元素个数 while(ssgroup)group=1; printf("gsize=%d,group=%d,ss=%d===========/n",gs,group,ss); for(int i=0;i(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(begin,mid,end);//实现方法同上 }

(6)直接选择排序(不稳定)

 /*用法 int buf[]={7,3,5,2,4,9,3,12,1,6}; csort(buf,&buf[10]); */ template void csort(T* begin,T* end){ for(T* b=begin;b!=end;++b){ T* n=b; ++n; bool op=false; while(n!=end){ T v=*b; if(*n

(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(cout," ")); */ #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template void qsort(T begin,T end){ 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){ if(*begin>*left){//找到了更小的数 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){
for(int g=sqr(s);g>1;g=sqr(g)){//分组
   size_t gs=s/g;//gs 是 group size
   for(int n=0;n    isort(begin+n*g, g, g);
   }//每个组的所有元素
   if(gs*g}//若干个组
}

(9)最后隆重推出百万级俱乐部成员: 堆排序。程序模板在gcc3.4.2下验证通过
#include #include #include #include #include using namespace std; #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template void hadjust(T heap,size_t len){ 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]){ --sub; continue; } swap(heap[sub-1],heap[csub-1]); --sub; } } template void hsort(T heap,size_t s){ while(s>1){ hadjust(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}; hsort(buf,12); copy(&buf[0],&buf[12],ostream_iterator(cout," ")); system("PAUSE"); return 0; }

// HeapSortTest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include using namespace std; #define swap(x,y) (x)^=(y);(y)^=(x);(x)^=(y) template void hadjust(T heap,size_t len) { 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]) { --sub; continue; } swap(heap[sub-1],heap[csub-1]); --sub; } } template void hsort(T heap,size_t s) { while(s>1) { hadjust(heap,s); swap(heap[0],heap[s-1]); --s; } } int _tmain(int argc, _TCHAR* argv[]) { // int buf[]={17,3,15,2,4,9,3,12,1,6,8,12}; int buf[]={40,55,49,73,12,27,98,81,64,36}; hsort(buf,10); copy(&buf[0],&buf[10],ostream_iterator(cout," ")); cout<

你可能感兴趣的:(数据结构,c++,class,iterator,merge,算法)