您的位置:首页 > 其它

LintCode 整数排序 II

2017-06-18 17:01 302 查看
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 {

10555
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分别指向子序列左、右两端的下标s和t,令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)+n=4T(n/4)+2n

       ≤4(2T(n/8)+n/4)+2n=8T(n/8)+3n

           … … …

       ≤nT(1)+nlog2n=O(nlog2n)

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

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

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

平均情况:为O(nlog2n)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: