排序算法实现

对本文出现的排序算法的分析见http://blog.csdn.net/libinjlu/article/details/12859211

1.插入排序

template <typename Comparable>
void insertionSort(vector<Comparable>& a)
{
    int j;

    for(int p=1;p<a.size();p++)
    {
        Comparable tmp=a[p];

        for(j=p;j>0&&tmp<a[j-1];j--)
            a[j]=a[j-1];
        a[j]=tmp;
    }
}
有R个逆序,因此运行时间为O(R+N)。若逆序数为O(N),则以线性时间运行。R为N(N-1)/4,因此为Ω(N^2).

2.希尔排序(有时也叫缩减增量排序)

a.希尔排序(基于插入排序,使用希尔增量)

template <typename Comparable>
void shellsort(vector<Comparable>& a)
{
    for(int gap=a.size()/2;gap>0;gap/=2)
        for(int i=gap;i<a.size();i++)
        {
            Comparable tmp=a[i];
            int j=i;

            for(;j>=gap&&tmp<a[j-gap];j-=gap)
                a[j]=a[j-gap];
            a[j]=tmp;
        }
}

b.希尔排序(基于简单交换排序,使用希尔增量)

void shellsort(int v[],int n)//based on simple exchange sort
{
    int gap,i,j,temp;
    for(gap=n/2;gap>0;gap/=2)
        for(i=gap;i<n;i++)
            for(j=i-gap;j>=0&&v[j]>v[j+gap];j-=gap){
                temp=v[j];
                v[j]=v[j+gap];
                v[j+gap]=temp;
            }
}
使用希尔增量的希尔排序每一趟排序是插入排序或简单交换排序,因此最坏是O(N^2)的。

3.堆排序

inline int leftChild(int i)//root index is 0
{
    return 2*i+1;
}

template <typename Comparable>
void percDown(vector<Comparable>& a,int i,int n)
{
    int child;
    Comparable tmp;

    for(tmp=a[i];leftChild(i)<n;i=child)
    {
        child=leftChild(i);
        if(child!=n-1&&a[child]<a[child+1])//if there is right child
            child++;
        if(tmp<a[child])
            a[i]=a[child];
        else
            break;
    }
    a[i]=tmp;
}

template <typename Comparable>
void heapsort(vector<Comparable>& a)
{
    for(int i=a.size()/2;i>=0;i--)//buildHeap
        percDown(a,i,a.size());
    for(int j=a.size()-1;j>0;j--)    //deleteMax
    {
        swap(a[0],a[j]);//通过最大堆将数组以递增序排列,可节省一个辅助数组。
        percDown(a,0,j);
    }
}

构建堆花费O(N),然后执行N次deleteMax操作,每次花费O(log N)。因此总运行时间为O(N log N)。


4.归并排序

template <typename Comparable>
void merge(vector<Comparable>& a,vector<Comparable>&tmpArray,int leftPos,int rightPos,int rightEnd)
{
    int leftEnd=rightPos-1;
    int tmpPos=leftPos;
    int numElements=rightEnd-leftPos+1;

    while(leftPos<=leftEnd&&rightPos<=rightEnd)
    {
        if(a[leftPos]<a[rightPos])
            tmpArray[tmpPos++]=a[leftPos++];
        else
            tmpArray[tmpPos++]=a[rightPos++];
    }

    while(leftPos<=leftEnd)
        tmpArray[tmpPos++]=a[leftPos++];
    while(rightPos<=rightEnd)
        tmpArray[tmpPos++]=a[rightPos++];

    for(int i=0;i<numElements;i++,rightEnd--)
        a[rightEnd]=tmpArray[rightEnd];
}

template <typename Comparable>
void mergeSort(vector<Comparable>& a,
               vector<Comparable>& tmpArray,int left,int right)
{
    if(left<right)
    {
        int center=(left+right)/2;
        mergeSort(a,tmpArray,left,center);
        mergeSort(a,tmpArray,center+1,right);
        merge(a,tmpArray,left,center+1,right);
    }
}

template <typename Comparable>
void mergeSort(vector<Comparable>& a)
{
    vector<Comparable> tmpArray(a.size());

    mergeSort(a,tmpArray,0,a.size()-1);//单参驱动多参函数
}

O(N log N)。

5.快速排序

从左向右依次判断,取中间索引为分划枢纽:

//order v ascendent
void qsort(int v[],int left,int right)
{
    int i,last;
    void swap(int v[],int i,int j);


    if(left>=right)
        return;
    swap(v,left,(left+right)/2);//the element to depart 
    last=left;//to v[0]
    for(i=left+1;i<=right;i++)//depart
        if(v[i]<v[left])
            swap(v,++last,i);
    swap(v,left,last);//move the depart element to the right place
    qsort(v,left,last-1);//the left half
    qsort(v,last+1,right);//the right half

}
void swap(int v[],int i,int j)
{
    int temp;
    temp=v[i];
    v[i]=v[j];
    v[j]=temp;
}
从左右向中间判断,取中间值为分划枢纽:
template <typename Comparable>
void insertionSort(vector<Comparable>& a,int left,int right)
{
    int j;

    for(int p=left+1;p<=right;p++)
    {
        Comparable tmp=a[p];

        for(j=p;j>0&&tmp<a[j-1];j--)
            a[j]=a[j-1];
        a[j]=tmp;
    }
}

/**
*Return median of left,center,right.
*Order these and hide the pivot.
*/
template <typename Comparable>
const Comparable& median3(vector<Comparable>& a,int left,int right)
{
    int center=(left+right)/2;

    if(a[center]<a[left])
        swap(a[left],a[center]);
    if(a[right]<a[left])
        swap(a[right],a[left]);
    if(a[right]<a[center])
        swap(a[right],a[center]);

    swap(a[center],a[right-1]);//place pivot at position right-1
    return a[right-1];
}

template <typename Comparable>
void quicksort(vector<Comparable>& a,int left,int right)
{
    if(left+10<=right)//qsort
    {
        Comparable pivot=median3(a,left,right);

        //Begin partitioning
        int i=left,j=right-1;
        for(;;)
        {
            while(a[++i]<pivot);
            while(pivot<a[--j]);
            if(i<j)
                swap(a[i],a[j]);
            else
                break;
        }

        swap(a[i],a[right-1]);//Restore pivot

        quicksort(a,left,i-1);
        quicksort(a,i+1,right);
    }
    else//insertion sort on the subarray
        insertionSort(a,left,right);
}

template <typename Comparable>
void quicksort(vector<Comparable>& a)
{
    quicksort(a,0,a.size()-1);
}
快速选择:
//to find the kth smallest
//place it in a[k-1]
template <typename Comparable>
void quickSelect(vector<Comparable>& a,int left,int right,int k)
{
    if(left+10<=right)//qsort
    {
        Comparable pivot=median3(a,left,right);

        //Begin partitioning
        int i=left,j=right-1;
        for(;;)
        {
            while(a[++i]<pivot);
            while(pivot<a[--j]);
            if(i<j)
                swap(a[i],a[j]);
            else
                break;
        }

        swap(a[i],a[right-1]);//Restore pivot

        if(k<=i)
            quickSelect(a,left,i-1,k);
        else if(k>i+1)
            quickSelect(a,i+1,right,k);
        //succeed !!
    }
    else//insertion sort on the subarray
        insertionSort(a,left,right);
}
最坏是O(N^2),平均为O(N)
6.间接排序(对象占用空间大,复制开销大)

template <typename Comparable>
class Pointer
{
public:
    Pointer(Comparable *rhs=NULL):pointee(rhs){};
    bool operator<(const Pointer& rhs)const//for compare in quicksort
    {
        return *pointee<*rhs.pointee;
    }
    operator Comparable*()const//类型转换
    {
        return pointee;
    }

private:
    Comparable* pointee;
};

template <typename Comparable>
void largeObjectSort(vector<Comparable>& a)
{
    vector<Pointer<Comparable> > p(a.size());
    int i,j,nextj;

    for(i=0;i<a.size();i++)
        p[i]=&a[i];

    quicksort(p);

    //shuffle items in place
    for(i=0;i<a.size();i++)
        if(p[i]!=&a[i])
        {
            Comparable tmp=a[i];
            for(j=i;p[j]!=&a[i];j=nextj)
            {
                nextj=p[j]-&a[0];
                a[j]=*p[j];
                p[j]=&a[j];
            }
            a[j]=tmp;
            p[j]=&a[j];
        }
}
最坏的情况为3N/2次复制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值