• 分治法排序


    分治模式在每一层递归上都有三个步骤:

    (1)分解(divide):将原问题分解成一系列子问题;

    (2)解决(conquer):递归的解各个子问题。若子问题足够小,则直接求解;

    (3)合并(combine):将子问题的结果合并成原问题的解。

    合并排序(merge sort)算法完全依照了上述模式,直观的操作如下:

    a.分解:将n个元素分成各含n/2个元素的子序列;

    b.解决:用合并排序法对两个子序列递归地排序;

    c.合并:合并两个已排序的子序列以得到排序结果。

    假设子数组A[p...q]和A[q+1...r]都已排好序,并将它们合并成一个已排序的子数组代替当前子数组A[p...r]

    伪代码实现如下:

    Merge_Array(A,first,mid,last)      //Merge(V[],first,mid,last)
        n1 <-- mid-first+1
        n2 <-- last-mid
        Creat arrays L[1...n1+1] and R[1...n2+1]
        for i=1 to n1
            do L[i] <-- A[first+i-1]   //Left
        for j=1 to n2
            do R[j] <-- A[mid+j]       //Right
        L[n1+1] <-- ∞
        R[n2+1] <-- ∞
        i=1
        j=1
        for k=first to last
            do if L[i] <= R[j]
                  then A[k] <-- L[i]
                  i =i+1
           else
             A[k] <-- R[j]    
      j = j+1

    现在可以将Merge_Array过程作为合并排序中的一个子程序来使用,下面的过程Merge_Sort(A,first,last)对子数组

    A[first...last]进行排序。如果平first>=last,则该数组至多只有一个元素,当然就是已排序。否则,分解步骤就计算

    出一个下标mid,将A[first...mid]和A[mid+1...last],各含[n/2]个元素。

    Merge_sort(A,first,last)
        if first<last
            then mid=[(first+last)/2]
            Merge_sort(A,first,mid)
            Merge_sort(A,mid+1,last)
            Merge_Array(A,first,mid,last)

     代码实现如下:

    #include<iostream>
    using namespace std;
    
    //合并排序的合并程序他合并数组Arr[]中位置为[first,mid] 和(mid,last]
    void Merge_Array(int A[],int first,int mid,int last)
    {
        int* tmp = new int[last-first+1];
        int k=0;
        int i=first;
        int j=mid+1;
        while(i<mid+1&&j<last+1)
        {
            if(A[i]<=A[j])
                tmp[k++]=A[i++];
            else
                tmp[k++]=A[j++];
        }
        while(i<mid+1)
            tmp[k++]=A[i++];
        while(j<last+1)
            tmp[k++]=A[j++];
        k=0;
        for(int m=first;m<last+1;m++)
            A[m]=tmp[k++];
        delete tmp;
        tmp=NULL;
    }
    
    void Merge_Sort(int Arr[],int start,int end)
    {
        if(start<end)
        {
            int mid=(start+end)/2;
            Merge_Sort(Arr,start,mid);          //左侧排序[first,mid]
            Merge_Sort(Arr,mid+1,end);         //右侧排序[mid+1,last]
            Merge_Array(Arr,start,mid,end);    //合并已排序的两个子数组
        }
    }
    
    int main()
    {
        int a[8]={5,2,4,7,1,3,2,6};
        Merge_Sort(a,0,7);
        for(int i=0;i<8;i++)
            printf("%d	",a[i]);
        return 0;
    }
  • 相关阅读:
    WebAPi返回类型到底应该是什么才合适,这是个问题?
    NuGet程序包安装SQLite后完全抽离出SQLite之入门介绍及注意事项,你真的懂了吗?
    完全抽离WebAPi之特殊需求返回HTML、Css、JS、Image
    模板引擎Nvelocity实例
    C#由变量捕获引起对闭包的思考
    AngularJS之指令中controller与link(十二)
    AngularJS之ng-class(十一)
    AngularJS之WebAPi上传(十)
    AngularJS之代码风格36条建议【一】(九)
    两个List合并去重
  • 原文地址:https://www.cnblogs.com/fuxianfeng1988/p/3307016.html
Copyright © 2020-2023  润新知