分治法排序

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

(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\t",a[i]);
    return 0;
}

 

 

 

posted on 2013-09-07 10:40  大浪 淘沙  阅读(929)  评论(0编辑  收藏  举报

导航