分治法排序

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

(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;
}

 

 

 

转载于:https://www.cnblogs.com/fuxianfeng1988/p/3307016.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
c语言的分治法快速排序是一种高效的排序算法。它通过选择一个基准元素,将数组分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于等于基准元素,然后对这两个子数组进行递归排序,最终得到有序的数组。 快速排序的具体步骤如下: 1. 选择一个基准元素x,通常可以选择数组的第一个元素或者中间的元素。 2. 设置两个指针i和j,分别指向数组的首尾元素。 3. 从i开始向后搜索,找到第一个大于等于x的元素。 4. 从j开始向前搜索,找到第一个小于等于x的元素。 5. 如果i小于j,则交换i和j所指向的元素。 6. 重复步骤3-5,直到i>=j。 7. 将基准元素x与j所指向的元素交换位置,这样就将数组分成了两部分。 8. 对两个子数组分别进行递归排序,即对左边子数组和右边子数组重复步骤1-7。 下面是使用C语言实现分治法快速排序的示例代码: ```c #include <stdio.h> void quick_sort(int q[], int l, int r) { if (l >= r) return; int i = l - 1, j = r + 1, x = q[(l + r) >> 1]; while (i < j) { do i++; while (q[i] < x); do j--; while (q[j] > x); if (i < j) { int t = q[i]; q[i] = q[j]; q[j] = t; } } quick_sort(q, l, j); quick_sort(q, j + 1, r); } int main() { int n; scanf("%d", &n); int q[n]; for (int i = 0; i < n; i++) scanf("%d", &q[i]); quick_sort(q, 0, n - 1); for (int i = 0; i < n; i++) printf("%d ", q[i]); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值