归并排序,分治思想

merge函数将两列有序序列合成一列。

merge_sort 函数使用分治思想,递归求解。将对一个序列排序转换成对左右两个序列排序,一直到序列长度为一时,递归开始回升。再将左右两个已经排好序的序列合并。

//
//  main.cpp
//  merge_sort
//
//  Created by Fangpin on 15/3/9.
//  Copyright (c) 2015年 FangPin. All rights reserved.
//

#include <iostream>
#include <cstdio>
const int MAXN=1e10;
int a[20006],b[20005],c[20005];
void merge(int p,int q,int r){
    int j=0;
    for(int i=p;i<=q;++i) b[j++]=a[i];
    b[j]=MAXN;j=0;
    for(int i=q+1;i<=r;++i) c[j++]=a[i];
    c[j]=MAXN;j=0;
    int k=0;
    for(int i=p;i<=r;++i){
        if(b[j]<=c[k])
            a[i]=b[j++];
        else a[i]=c[k++];
    }
}

void merge_sort(int l,int r){
    if(l>=r) return;
    int m=(l+r)>>1;
    merge_sort(l,m);
    merge_sort(m+1,r);
    merge(l,m,r);
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i<n;++i){
            scanf("%d",&a[i]);
        }
        merge_sort(0,n-1);
        for(int i=0;i<n;++i){
            if(i) printf(" ");
            printf("%d",a[i]);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-28 15:49:46

归并排序,分治思想的相关文章

分治思想--小测试(归并排序后续)

1 package cn.it; 2 3 import java.util.Arrays; 4 // 利用分治思想 实现 归并排序 5 public class Fz { 6 public static void main(String[] args) { 7 int a[]={1,2,3,4,5,6,8,7,3,4,9,0}; 8 int temp[] = new int[a.length]; 9 sortdiv(a, 0, a.length-1, temp); 10 System.out.p

排序算法大集锦_二路归并排序_2&3(分治思想)

第一段代码和合并排序差不多,用它来和第二段代码--二路归并排序作对比. 这一系列博客的特点就是--给出每趟排序的结果 本来想着好好写一下过程,弄个图片什么的,不过觉得网上的解析太多了,都比较好,所以这些博客就算是对自己的总结吧. #include <stdio.h> #include <limits.h> #include <malloc.h> void merge(int *m, int x, int y, int z) { int b1,b2,i,j,k; b1=y

经典算法宝典——分治思想(四)(1)

分治法(Divide and Conquer)的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的几个相似问题,以便各个击破,分而治之. 说明: 分治策略的应用很广,具体表现形式各异,比如:折半查找.合并排序.快速排序.二叉树遍历(先遍历左子树再遍历右子树).二叉排序树的查找等算法. 一.分治算法框架 1.算法设计思想 分治法求解问题的过程是,将整个问题分解成若干个小问题后分而治之.如果分解得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出方

一次性弄懂到底什么叫做分治思想(含有大量经典例题,附带详细解析)

期末了,通过写博客的方式复习一下算法,把自己知道的全部写出来 分治:分而治之,把一个复杂的问题分解成很多规模较小的子问题,然后解决这些子问题,把解决的子问题合并起来,大问题就解决了 但是我们应该在什么时候用分治呢?这个问题也困扰了我很久,做题的时候就不知道用什么算法 能用分治法的基本特征: 1.问题缩小到一定规模容易解决 2.分解成的子问题是相同种类的子问题,即该问题具有最优子结构性质 3.分解而成的小问题在解决之后要可以合并 4.子问题是相互独立的,即子问题之间没有公共的子问题 第一条大多数问

算法--分治思想的运用

前言:上次算法课主要对分治思想进行了介绍,在这里进行以下总结和几个例子的应用. 一.分治算法 设计过程:(1)分解:将问题分解为子问题,子问题的形式与原问题是一样的,只是规模减小了. (2)求解:递归地求解出子问题. (3)合并:将子问题的解组合成原问题的解. 分治算法中最重要的就是递归求解子问题,求解递归式估计出算法的复杂度一般可以有三种方式: (1)代入法:猜测一个界,然后用数学归纳法证明这个界是正确的. (2)递归树法:将递归式转为一棵树,其结点表示不同层次的递归调用产生的代价. (3)主

动态规划_基础_任意子区间序列求和问题_滑动窗口解法_多种思路_分治思想演变

题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入描述 第一行是一个正整数 N ( 1 ≤ N ≤ 200000 ) ,表示了序列的长度. 接下来的 N 行包含 N 个绝对值不大于 10000 的整数 A [ i ] ,描述了这段序列. 输出描述 仅包括 1 个整数,为最大的子段和是多少,子段的最小长度为 1 . 样例输入 72-43-12-43 样例输出 4 Hint Origin: SidneyEdit by stdKonjac in 2020 解题思路: 关于求子区间求

分治思想在Trimino拼图中的Java实现

近期学习<算法设计与分析基础 第二版>,学习到了分治法,被课后习题吸引了,即Trimino拼图问题.想了好久,都没有想到如何去分而治之.然后就是Google到了相关的PPT.一看就明白了.自己就用代码实现了下.理解思想后,代码实现挺容易的. 这个谜题实际上可以做成一个小益智游戏. 分治思想的关键就在于构造相同的子问题.这是这个思想核心看似简单,实则需要对问题的洞察力.看到的PPT核心图如下: 算法的源代码如下: /**  * @author shuaiguangying  * 用分治法解决棋盘

归并排序 分治+递归

0      1    2     3     4     5     6     7     8   //下标 {  9  ,  4  ,  3  ,  7  ,  3  ,  8  ,  2  ,  4  ,  8  }//通过mergesort函数递归 来切 开始的时候fir=0, las=8, mid=4  所以下标0-4,分为前组   5-8分为后组 {  9  , 4   ,  3  ,  7  ,  3 }{ 8   , 2   , 4  ,  8  } {  9   , 4  ,

归并排序算法思想

归并排序 ###### 这次我们来讲述归并排序的基本思想. 归并排序,首先把一个数组中的元素,按照某一方法,先拆分了之后,按照一定的顺序各自排列,然后再归并到一起,使得归并后依然是有一定顺序的 . 归并排序算法可以利用递归的思想或者迭代的思想去实现.首先我们先把一个无序的数组去拆分,然后利用一定的规则,去合并.类似于二叉树的结构.其总的时间复杂度为O( n log n). 示例图如下: 首先我们看到,一个无序的数组如下,为了简约,以及简便解释,我们定义了8个元素. 然后,我们把该8个元素进行划分