第49课 - 归并排序和快速排序

1、归并排序

        归并排序的基本思想

                -将两个或两个以上的有序序列合并成—个新的有序序列 

                   有序序列V[0]…V[m]和V[m+1]…V[n-1]    V[0]…V[n-1]

                   这种归并方法称为 2 路归并


        归并的套路 

                -将3个有序序列归并为—个新的有序序列,称为 3 路归并 

                -将N个有序序列归并为—个新的有序序列,称为 N 路归并 

                -将多个有序序列归并为—个新的有序序列,称为多路归并 


        2路归并示例 

                


        归并排序的代码实现 

              


2、编程实验 

归并排序的实现     Sort::Merge
#ifndef SORT_H
#define SORT_H

#include"Object.h"

namespace DTLib
{

class Sort : public Object
{
private:
    Sort();
    Sort(const Sort&);
    Sort& operator = (const Sort&);

    template <typename T>
    static void Swap(T& a,T& b)
    {
        T t(a);
        a = b;
        b = t;
    }
    template < typename T>
    static void Merge(T src[],T helper[],int begin,int mid,int end,bool min2max)   //归并
    {
        int i = begin;
        int j = mid + 1;
        int k = begin;  //辅助空间起始位置

        while(i <= mid && j <= end)
        {
            if(min2max ? (src[i] < src[j]) : (src[i] > src[j]))
            {
                helper[k++] = src[i++];
            }
            else
            {
                helper[k++] = src[j++];
            }
        }

        while(i <= mid)
        {
            helper[k++] = src[i++];
        }

        while(j <= end)
        {
            helper[k++] = src[j++];
        }

        for(i=begin;i<=end;i++)
        {
            src[i] = helper[i];
        }
    }

    template < typename T>
    static void Merge(T src[],T helper[],int begin,int end,bool min2max)
    {   

        if(begin < end)
        {
            int mid = (begin + end) / 2;

            Merge(src, helper, begin, mid, min2max);    //左边 二路归并排序==》左边有序
            Merge(src, helper, mid+1, end, min2max);    //右边 二路归并排序==》右边有序
            Merge(src, helper, begin, mid, end, min2max);   
        }
    }


public:

    template < typename T>
    static void Merge(T array[],int len,bool min2max=true)
    {
        T* helper = new T[len];

        if(helper != NULL)
        {
            Merge(array, helper, 0, len-1, min2max);
        }

        delete[] helper;
    }
};
}


#endif // SORT_H

main.cpp

#include <iostream>
#include"Sort.h"

using namespace std;
using namespace DTLib;



int main()
{

    int array[] = {7,9,4,6,2,1,3,8,0,5};

    Sort::Merge(array,10);

    for(int i=0;i<10;i++)
    {
        cout<<array[i]<<" ";
    }

    cout<<endl;

    Sort::Merge(array,10,0);

    for(int i=0;i<10;i++)
    {
        cout<<array[i]<<" ";
    }

    cout<<endl;

    return 0;
}

                        


3、快速排序

            快速排序的基本思想 

                -任取序列中的某个数据元素作为基准将整个序列划分为左右两个 

                    子序列 

                        左侧子序列中所有元素都小于或等于基准元素 

                              右侧子序列中所有元素都大于基准元素

                               基准元素排在这两个子序列中间 

                -分别对这两个子序列重复进行划分,直到所有的数据元素都排在 

                    相应位置上为止 


            快速排序示例 

            

                



4、编程实验 

快速排序的实现     Sort::Quick
#ifndef SORT_H
#define SORT_H

#include"Object.h"

namespace DTLib
{

class Sort : public Object
{
private:
    Sort();
    Sort(const Sort&);
    Sort& operator = (const Sort&);

    template <typename T>
    static void Swap(T& a,T& b)
    {
        T t(a);
        a = b;
        b = t;
    }
 
    template < typename T >
    static int Partition(T array[],int begin,int end,bool min2max)
    {
        T pv = array[begin];

        while(begin < end)
        {
            while( (begin < end) && ( min2max ? (array[end] > pv) : (array[end] < pv) ) )
            {
                end--;
            }

            Swap(array[begin],array[end]);

            while( (begin < end) && ( min2max ? (array[begin] <= pv) : (array[begin] >= pv) ) )
            {
                begin++;
            }

            Swap(array[begin],array[end]);

        }

        array[begin] = pv;

        return begin;
    }

    template < typename T >
    static void Quick(T array[],int begin,int end,bool min2max)
    {
        if(begin < end)
        {
            int pivot = Partition(array,begin,end,min2max);

            Quick(array,begin,pivot-1,min2max);
            Quick(array,pivot+1,end,min2max);
        }
    }

public:
    
    template < typename T >
    static void Quick(T array[],int len,bool min2max=true)
    {
        Quick(array,0,len-1,min2max);
    }

};
}


#endif // SORT_H

main.cpp

#include <iostream>
#include"Sort.h"

using namespace std;
using namespace DTLib;



int main()
{

    int array[] = {7,9,4,6,2,1,3,8,0,5};

    Sort::Quick(array,10);

    for(int i=0;i<10;i++)
    {
        cout<<array[i]<<" ";
    }

    cout<<endl;

    Sort::Quick(array,10,0);

    for(int i=0;i<10;i++)
    {
        cout<<array[i]<<" ";
    }

    cout<<endl;

    return 0;
}


                           


5、小结 

            归并排序需要额外的辅助空间才能完成,空间复杂度为O(n

            归并排序的时间复杂度为O(n*logn) , 是—种稳定的排序法 

            快速排序通过递归的方式对排序问题进行划分 

            快速排序的时间复杂度为O(n*logn) , 是—种不稳定的排序法


猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80435925