Day-2

来源:互联网 发布:水牛 黄牛 知乎 编辑:程序博客网 时间:2024/05/16 00:58

一、四种基本的排序方法(以由大到小为例)及空间时间复杂度:

1)简单排序

void xz_sort(int a[],int n)

{
    int i,j,t,max;
    for(i=0;i<n-1;i++)                  //第i+1个数与后面的数比较
    {
        max=i;
        for(j=i+1;j<n;j++)              //分别与后面的数作比较
            if(a[max]<a[j])   max=j;        //找到符合要求顺序的就给改变下标
        if(max!=i)  t=a[max],a[max]=a[i],a[i]=t;
    }

}

2)冒泡排序

void mp_sort(int a[],int n)
{
    int i,j;
    int t;
    for(i=0;i<n-1;i++)                           //每次循环后保留后面i+1个数
        for(j=0;j<n-1-i;j++)                     //比较n-1-i次大小
            if(a[j]<a[j+1]) t=a[j+1],a[j+1]=a[j],a[j]=t;
}

3)插入排序

void cr_scort(int a[],int n)
{
    int i,j,t;
    for(i=1;i<n;i++)                    //全扫一遍研究值
    {
        t=a[i];                         //保留研究值
        j=i;                            //制造多个变量,不用i的原因是二重循环中会改变i值,导致混乱
        while(j>0&&t>a[j-1])            //整体的循环对前i个数排好顺序,直到找到比研究值大的前一位数停止。这时该研究值的下标为j
        {
            a[j]=a[j-1];                //当找到比研究值大的数,就用a[i-1]填a[i]
            j--;                        //作用:使前面的数值有序
        }
        a[j]=t;                         //补坑(注:前面的j--)
    }

4)折半插入排序

/*void zbcr_scort(int a[],int n)
{
    int j,i,x,r,l;
    for(i=1;i<n;i++)
    {
        l=0,r=i-1;
        x=a[i];
        int m=(l+r)/2;

//二分找应插入的位置
        while(l<=r&&x!=a[m])
        {
            if(x<a[m])  l=m+1;
            else if(x>=a[m])    r=m-1;
            m=(l+r)/2;
        }
        for(j=i;j>=l;j--)                    //注:j>=l。因为导致while循环退出后l>r故应插入的位置为r~l之间
            a[j]=a[j-1];
        a[l]=x;
    }
}

=====================================================================================================

排序方法最好情况最坏情况平均情况稳定性空间复杂度冒泡排序O(n)O(n^2)O(n^2)稳定0(1)快速排序O(nlogn)O(n^2)O(nlogn)不稳定0(logn)简单选择排序O(n^2)O(n^2)O(n^2)不稳定0(1)堆排序O(nlogn)O(nlogn)O(nlogn)不稳定0(1)直接插入排序O(n)O(n^2)O(n^2)稳定0(1)折半插入排序  O(n^2)稳定 0(1)希尔排序  O(n1.3)不稳定0(1)归并排序O(nlogn)O(nlogn)O(nlogn)稳定O(n)基数排序  O(d(r+n))稳定O(n)










===============================================================

二、快速排序的理解

以由大到小的顺序排序为例:

void quick_sort(int a[],int l,int r)
{


    int axis;
    if(l<r)                       //中轴axis
    {
        axis=adjust(a,l,r);
        quick_sort(a,l,axis-1);
        quick_sort(a,axis+1,r);
    }
}
int adjust(int a[],int l,int r)                 //有思想,有看头
{
    int x=a[l];
    while(l<r)
    {
        while(l<r&&x<=a[r])             //若符合由小到大的规律
            r--;                        //改变指向以保留
        a[l]=a[r];                      //有重复
        while(l<r&&x>=a[l])
            l++;
        a[r]=a[l];
    }
    a[l]=x;
    return l;
}

解题步骤:

a.把第一个数(研究数)付给中间值t,空出空位

b.若右边的数找到比t大的数时,把空填上,并再次空出一个空位。

c.再如果从左往右找到比t小的数时,把该数赋给空位,并再次空出一空位。

d.重复b、c直到研究数左边的都是大于其的数,有右边的都是小于其的数。

e.不断平分左右区间,重复b~d步骤,直到平分的区间只有一个元素。



0 0