秋林箭

每夜,携酒河上,饮且渔

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

冒泡

交换相邻的点使得最小的点排到最前,同时后面的点一定程度上也排序。

#include<iostream>
#include<string>
using namespace std;

void Bubble(int *list,int length)
{
    bool flag=true;
    for(int i=0;i<=length-1&&flag;i++)
    {
        flag=false;
        for(int j=length-1;j>=i+1;j--)
        {
            if(list[j]<list[j-1])
            {
                int temp=list[j];
                list[j]=list[j-1];
                list[j-1]=temp;
                flag=true;
            }
        }
    }
}

简单选择

查找最小的点,把它放到最前面。

void SelectSort(int * list ,int length)
{
    for(int i=0;i<length-1;i++)
    {
        int min=i;
        for(int j=i+1;j<length;j++)
        {
            if(list[j]<list[min])
            {
                min=j;
            }
        }
        if(i!=min)
        {
            int temp=list[min];
            list[min]=list[i];
            list[i]=temp;
        }
    }

}

直接插入

将第i+1个点插入到已排好序的前i个点中。

void InsertSort(int* list ,int length)
{
    for(int i=1;i<length;i++)//已经排好前i个数,处理第i+1个即下标i的
    {
        int j=i-1;//前i个中的最后一个的下标
        int tempi=list[i];
        for(;j>=0&&tempi<list[j];j--)
        {
            list[j+1]=list[j];
        }
        list[j+1]=tempi;
    }

}

希尔

其实有点类似直接插入,是分成好几组进行的。增量序列为dlta[k]=2t-k+1-1(0<=k<=t<=log2(n+1))。

第一层do while循环是increment逐次减一,直到increment1

第二层for循环是比较ii+increment项,i从头到尾

第三层for循环是为了移动,将比第i+increment项大的都向后移

void ShellSort(int*list,int length)
{
    int increment=length/3+1;
    do
    {
        increment=increment/3+1;
        for(int i=0;i<=length-increment-1;++i)
        {
            int temp=list[i+increment];
            int j=i;
            for(;j>=0&&temp<list[j];j-=increment)
            {
                list[j+increment]=list[j];
            }
            list[j+increment]=temp;
        }
    }while(increment>1);
}

堆排序

先构建最大堆,即先将子树变成最大堆,交换1号和最后一个,再将去掉最后一个的序列调整成最大堆

void heapcore(int *list,int s,int m)
{
    int temp=list[s];
    int j=2*s;
    for(;j<=m;j*=2)
    {
        if(j<m&&list[j]<list[j+1])
            j++;
        if(temp>=list[j])
            break;
        list[j/2]=list[j];
        list[j]=temp;
    }
}
void HeapSort(int*list ,int length)
{
    for(int i=(length-1)/2;i>=1;--i)
    {
        heapcore(list,i,length-1);
    }
    for(int i=length-1;i>=2;--i)
    {
        int temp=list[1];
        list[1]=list[i];
        list[i]=temp;
        heapcore(list,1,i-1);
    }
}

快速

先随机选择一个数,将小于它的放在左边,大于的放在右边。返回该数的位置,然后处理左边序列,右边序列其中放置其他数的方法是,设置一个small标志,从start开始,遇到比轴小的就交换ismall位置的数,small1

int partition(int *list ,int start,int end)
{
    int idex=rand()%(end-start+1)+start;
    int small=start;
    int key=list[idex];
    list[idex]=list[end];
    list[end]=key;
    for(int i=start;i<end;i++)
    {
        if(list[i]<key)
        {
            int temp=list[small];
            list[small]=list[i];
            list[i]=temp;
            small++;
        }

    }
    int temp=list[small];
    list[small]=list[end];
    list[end]=temp;
    return small;
}
void QSort(int*list,int start,int end)
{
    int id=partition(list ,start,end);
    if(id>start)
        QSort(list,start,id-1);
    if(id<end)
        QSort(list,id+1,end);
}
void QuickSort(int*list,int length)
{
    QSort(list,0,length-1);
}

归并

先两个两个的,再四个四个的,后八个八个的排。。。

//排s1~s2-1(有序),s2~end(有序)两段,排好放在temp
void Merge(int *list,int *temp,int s1,int s2,int end )
{
    int i=s1;
    int j=s2;
    int k=s1;
    while(i<=s2-1&&j<=end)
    {
        if(list[i]<list[j])
        {
            temp[k]=list[i];
            i++;
            k++;
        }
        else
        {
            temp[k]=list[j];
            j++;
            k++;    
        }
    }
    if(i<=s2-1)
    {
        while(i<=s2-1)
        {
            temp[k]=list[i];
            i++;
            k++;
        }
    }
    if(j<=end)
    {
        while(j<=end)
        {
            temp[k]=list[j];
            j++;
            k++;
        }
    }
}
//从第0个开始,相邻两个k个合并,即0~k-1,k~2k-1合并,2k~3k-1,3k~4k-1合并。。。
void MSort(int*list,int *temp,int k,int length)
{
    int i=0;
    //i是第一个k个的第一个i+2k-1是第二个k个的最后一个,要保证在长度范围内
    for(;i+2*k-1<=length-1;i=i+2*k)
    {
        Merge(list,temp,i,i+k,i+2*k-1);
    }
    //剩下的不足2k个,可能>k&&<2k或者<=k
    //i+k-1是第二个k个的第一个,说明存在第二个k个,需要合并
    if(i+k-1<=length-1)
    {
        Merge(list,temp,i,i+k,length-1);
    }
    //不足k个,不用合并,直接复制
    else
    {
        for(int j=i;j<=length-1;j++)
        temp[j]=list[i];
    }
}
void MergeSort(int*list,int length)
{
    int *temp=new int[length];
    int k=1;
    while(k<length)
    {
    //这样做主要是为了将temp合并到list里面
        MSort(list,temp,k,length);
        k*=2;
        MSort(temp,list,k,length);
        k*=2;
    }
    delete[] temp;
}

 

int main()
{
    int a[1000];
    int i=0;
    int c;
    while(cin>>c)
    {
        a[i]=c;
        i++;        
        if(cin.get()=='\n')
        break;
    }
    //Bubble(a,i);
    //SelectSort(a,i);
    //InsertSort(a,i);
    //ShellSort(a,i);
    //HeapSort(a,i);
    //QuickSort(a,i);
    MergeSort(a,i);
    for(int j=0;j<i;j++)
    {
        cout<<a[j]<<" ";
    }
}

 

posted on 2015-08-08 09:05  zhangyee  阅读(181)  评论(0编辑  收藏  举报