LintCode 整数排序 II

来源:互联网 发布:游戏主机历史 知乎 编辑:程序博客网 时间:2024/06/06 05:02

1.描述

给一组整数,按照升序排序。使用归并排序,快速排序,堆排序或者任何其他 O(n log n) 的排序算法。

2.分析

如题,一般排序为o(n)算法,若涉及到两组数据多重循环排序时甚至会到达o(n*2)的复杂度,

这里采用的是o(n log n)快速排序,基本思想为选取一个元素使排在其前面的元素比它小,排在后面的

元素比它大,达成一个基本有序的情况进而减小运算规模。

3.代码

class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};class Solution {
public:
    /**
     * @param A an integer array
     * @return void
     */
    int Partition(vector<int>& A,int first,int end)
    {
        int i=first;
        int j=end;
        int t;
        while(i<j)
        {
            while(i<j&&A[i]<=A[j]) j--;
            if(i<j)
            {
                t=A[i];
                A[i]=A[j];
                A[j]=t;
                i++;
            }
            while(i<j&&A[i]<=A[j]) i++;
            if(i<j)
            {
                t=A[j];
                A[j]=A[i];
                A[i]=t;
                j--;
            }
        }
        return i;
    }
    void QuickSort(vector<int>& A,int first,int end)
    {
        if(first<end)
        {
            int pivot=Partition(A,first,end);
            QuickSort(A,first,pivot-1);
            QuickSort(A,pivot+1,end);
        }
    }
    void sortIntegers2(vector<int>& A) {
        // Write your code here
        QuickSort(A,0,A.size()-1);
    }
};

4.总结

快速排序的基本思想

首先选一个轴值(即比较的基准),

通过一趟排序将待排序记录分割成独立的两部分,

前一部分记录的关键码均小于或等于轴值,

后一部分记录的关键码均大于或等于轴值,

然后分别对这两部分重复上述方法,直到整个序列有序。

关键问题⑴:如何选择轴值?

选择轴值的方法:

1.使用第一个记录的关键码;

2.选取序列中间记录的关键码;

3.比较序列中第一个记录、最后一个记录和中间记录的关键码,取关键码居中的作为轴值并调换到第一个记录的位置;

4.随机选取轴值。

选取不同轴值的后果:

决定两个子序列的长度,子序列的长度最好相等。

关键问题⑵:如何实现一次划分?

解决方法:

设待划分的序列是A[s] ~ A[t],设参数i,j分别指向子序列左、右两端的下标st,令A[s]为轴值,将轴值放入A[0]中。

(1)j从后向前扫描,直到A[j]<A[0],将A[j]移动到A[i]的位置,使关键码小(同轴值相比)的记录移动到前面去;

(2)i从前向后扫描,直到A[i]>A[0],将A[i]移动到A[j]的位置,使关键码大(同轴值比较)的记录移动到后面去;

(3)重复上述过程,直到i==j。

关键问题⑶:如何处理分割得到的两个待排序子序列?

算法描述:

void QuickSort (int  r[ ], int first, int end )

{

   pivotpos = Partition (r, first, end ); //一次划分 

   //对前一个子序列进行快速排序

   QuickSort (r, first, pivotpos-1);     

   //对后一个子序列进行快速排序

  QuickSort (r, pivotpos+1, end );

}

关键问题⑷:如何判别快速排序的结束?

解决方法:

若待排序列中只有一个记录,显然已有序,排序结束;

否则进行一次划分后,再分别对分割所得的两个子序列进行快速排序(即递归处理)。

因此:递归的出口为first==end;

快速排序的时间性能分析

每次划分轴值的选取——>快速排序递归的深度——>快速排序的时间性能

最好情况:

每一次划分对一个记录定位后,该记录的左侧子表与右侧子表的长度相同,为O(nlog2n)。

T(n)≤2T(n/2)n

       ≤2(2T(n/4)n/2)n4T(n/4)2n

       ≤4(2T(n/8)n/4)2n8T(n/8)3n

           … … …

       ≤nT(1)nlog2nO(nlog2n)

每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空)

这样,总共需要进行n-1趟排序

i趟排序又要进行为 n-i次比较

平均情况:O(nlog2n)。





原创粉丝点击