C++排序算法总结

=================================================
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;
          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]);
    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){
     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){
                               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<sizeof(buf2)/sizeof(short);++i)printf("%d ",buf2[i]);
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;
     }
}

(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
#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<DEMICAL;++a){getb(a);} printf("/n");}
int main(int argc, char *argv[])
{
    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
      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 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){
                 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);//实现方法同上
}
 
/*用法
   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){
       T v=*b;
       if(*n<v){
           *n^=*b;
           *b^=*n;
           *n^=*b;
           op=true;
       }
       ++n;
     }
     if(op==false)return;
 }
}
 
/*用法
   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;
     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);
}
 
可以理解为直接插入排序的变体。这里只给出伪代码:
首先实现一个直接插入排序
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)){/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);//末尾剩余的元素
    }//若干个组
}
 
#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 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 <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};
   hsort(buf,12);
   copy(&buf[0],&buf[12],ostream_iterator<int>(cout," "));
   system("PAUSE");
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值