归并排序( •̀ ω •́ )y

26人阅读 评论(2) 收藏 举报

前言

菜鸟漫漫成长路第一部——归并排序。

归并排序

归并排序采用的是分治的思想。就是将我们的问题一步步分解,再一步步去合并。

治( •̀ ω •́ )y

首先我们假设有两个有序数组,那么我们怎么去合并他们呢?
(⊙﹏⊙)首先我们可以假设两个指针,p1,p2以及一个长度为两个有序数组之和的新数组。然后让他们分别指在这两个数组的第一个。好啦,我们的准备工作就做好啦~接下来我们就去比较p1 p2的大小,将小的那个数字放入到我们的新数组中,然后将指向这个数的指针后移一位,继续比较。一直重复重复,当有一个指针走完了整个数组,就将另一个数组剩下的全部放入到我们的新数组。嘻嘻,这样我们是不是就可以把两个有序数组合并成了一个新的有序数组呢( •̀ ω •́ )y。接下来看看一个很丑的图解!
这里写图片描述

分( •̀ ω •́ )y

问题就来了,要用上面的方法,我们必须是两个有序的数组呀。我们怎么去把一个无序的数组分成两个有序的数组呢?那么我们是不是可以用分解的办法呢。把一个数组分成两个,再将这两个数组分别分成两个…这样一直下去,直到分到我们的数组不能再分。然后再依次往上采用治的思想,咦,问题好像就解决了。( •̀ ω •́ )y。
这里写图片描述

code

使用递归的时候,我们递归之前的语句是顺序执行,递归之后的语句是逆序执行。因为我们的治是逆序的,所以应该放在递归语句后面。

public class MergeSort {

    public static void mergeSort(int[] a){
        if (a==null||a.length<2){
            return;
        }
        mergeSort(a,0,a.length-1);
    }
    public static void mergeSort(int[] a,int l,int r){
        if (l == r){
            return;
        }
        int mid = l+((r-l)/2);
        mergeSort(a,l,mid);
        mergeSort(a,mid+1,r);
        merge(a,l,r,mid);
    }

    private static void merge(int []a,int l,int r,int mid) {
        int[] help = new int[r-l+1];
        int i = 0;
        int p1 = l;
        int p2 = mid +1;
        while(p1 <= mid && p2 <= r){
            help[i++] = a[p1] < a[p2]? a[p1++] :a[p2++];
        }
        while(p1 <= mid){
            help[i++] = a[p1++];
        }
        while(p2 <= r){
            help[i++] = a[p2++];
        }
        for (int j = 0; j < help.length; j++) {
            a[l+j] = help[j];
        }
    }
    public static void main(String[] args) {
        int[] a = {1,2,3,4,6,5,2,4,5,4};
        mergeSort(a);
        for (int i : a) {
            System.out.print(i);
        }
    }


}

小和问题

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。

在治的过程中,修改一下其代码就好啦。

while(p1 <= mid && p2 <= r){
            sum += a[p1] < a[p2]? a[p1]*(r-p2+1):0;
            help[i++] = a[p1] < a[p2]? a[p1++] :a[p2++];
        }

逆序对问题

在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序对。

都是用分治的思想

public class MergeSort {

    public static int mergeSort(int[] a){
        if (a==null||a.length<2){
            return 0;
        }
        return mergeSort(a,0,a.length-1);
    }
    public static int mergeSort(int[] a,int l,int r){
        if (l == r){
            return 0;
        }
        int mid = l+((r-l)/2);
        return mergeSort(a,l,mid)+mergeSort(a,mid+1,r)+merge(a,l,r,mid);
    }

    private static int merge(int []a,int l,int r,int mid) {
        int[] help = new int[r-l+1];
        int i = 0;
        int p1 = l;
        int p2 = mid +1;
        int sum = 0;
        while(p1 <= mid && p2 <= r){
            sum += a[p1] > a[p2]? (mid - p1 + 1):0;
            help[i++] = a[p1] < a[p2]? a[p1++] :a[p2++];
        }
        while(p1 <= mid){
            help[i++] = a[p1++];
        }
        while(p2 <= r){
            help[i++] = a[p2++];
        }
        for (int j = 0; j < help.length; j++) {
            a[l+j] = help[j];
        }
        return sum;
    }
    public static void main(String[] args) {
        int[] a = {4,3,8,1};
        System.out.print(mergeSort(a));
    }


}
查看评论

使用OpenMP实现并行归并排序(Report)

归并排序算法:归并排序算法是一种经典的分治算法。分治分治算法分为由三部分组成: 分解:将原问题分解为一系列子问题; 解决:递归的解决各个子问题。若子问题足够小,那么直接求解。 合并:将子问题的结...
  • ACM_Fish
  • ACM_Fish
  • 2017-06-05 16:41:19
  • 1008

每天一种算法-归并排序

Java实现package bigo;public class merge { static void merge(int src[], int left,int right,int mid)...
  • u012063703
  • u012063703
  • 2016-04-26 17:46:33
  • 175

归并排序

把问题分割,分割,分割,最后就是答案了。
  • u012063703
  • u012063703
  • 2015-09-22 19:52:16
  • 302

深入浅出排序算法的多语言实现

深入浅出排序算法的多语言实现 转自: http://www.cnblogs.com/baiboy/p/sort.html 摘要:十一假期于实验室无趣,逐研究起数据结构之排序。起初觉得就...
  • zdy0_2004
  • zdy0_2004
  • 2015-10-08 23:54:32
  • 711

OpenMP并行编程计算π值及PSRS排序

OpenMP简介OpenMP是一个共享存储并行系统上的应用程序接口。它规范了一系列的编译制导、运行库例程和环境变量。它提供了C/C++和FORTRAN等的应用编程接口,已经应用到UNIX、Window...
  • rectsuly
  • rectsuly
  • 2017-04-08 23:11:06
  • 1866

Fortran-IMSL的下载与安装

Fortran-IMSL的下载与安装
  • u010909667
  • u010909667
  • 2017-06-29 16:59:30
  • 527

数据结构之排序_java实现篇

各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一、冒泡排序(BubbleSort) 1. 基...
  • LJX_ahut
  • LJX_ahut
  • 2017-08-17 16:40:25
  • 108

各种内部排序方法的比较和选择

各种内部排序方法的比较和选择按平均时间将排序分为四类:(1)平方阶(O(n2))排序     一般称为简单排序,例如直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlgn))排序     如快速...
  • dadunqingwa
  • dadunqingwa
  • 2005-07-30 16:18:00
  • 6437

各种排序算法java实现(极细致)

各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 http://blog.csdn.net/shanliangliuxing/article/details/...
  • gloria0610
  • gloria0610
  • 2014-05-13 17:01:50
  • 599
    个人资料
    持之以恒
    等级:
    访问量: 6969
    积分: 337
    排名: 23万+
    文章分类
    最新评论