Java分治归并排序算法实例详解


Posted in Python onDecember 12, 2017

本文实例讲述了Java分治归并排序算法。分享给大家供大家参考,具体如下:

1、分治法

许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题。这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。

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

(1)分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。
(2)解决这些子问题,递归地求解各子问题。然而,若子问题的规模足够小,则直接求解。
(3)合并这些子问题的解成原问题的解。

2、归并排序算法

归并排序算法完全遵循分治模式。直观上其操作如下:

(1)分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。
(2)解决:使用归并排序递归地排序两个子序列。
(3)合并:合并两个已排序的子序列以产生已排序的答案。

当待排序的序列长度为1时,递归“开始回升”,在这种情况下不要做任何工作,因为长度为1的每个序列都已排好序。归并排序算法的关键操作是“合并”步骤中两个已排序序列的合并。我们通过调用一个辅助过程Merge(A,p,q,r)来完成合并,其中A是一个数组,p、q和r是数组下标,满足p<=q<r。该过程假设子数组A[p,q]和A[q+1,r]都已排好序。它合并这两个子数组形成单一的已排好序的子数组并代替当前的子数组A[p,r]。

过程Merge按以下方式工作。回到我们玩扑克牌的例子,假设桌上有两堆牌面朝上的牌,每堆都已排序,最小的牌在顶上。我们希望把这两堆牌合并成单一的排好序的输出堆,牌面朝下地放在桌上。我们的基本步骤包括在牌面朝上的两堆牌的顶上两张牌中选取较小的一张,将该牌从其堆中移开(该堆的顶上将显露一张新牌)并牌面朝下地将该牌放置到输出堆。

下面是Merge的伪代码:

Merge(A,p,q,r):

tmp[1,..,r-p+1]
i = p
j = q+1
while i <= q && j <= r
  if A[i] <= A[j]
  tmp[k++] = A[i++];
  else
  tmp[k++] = A[j++];
  while i <= q
  tmp[k++] = A[i++];
  while j <= r
  tmp[k++] = A[j++];
  for k2 = 0 to tmp.length
  A[k2+p] = tmp[k2];

Java分治归并排序算法实例详解

现在我们可以把过程Merge作为归并排序算法中的一个子程序来用。下面的过程Merge_sort(A,p,r)排序子数组A[p,r]中的元素。若p>=r,则该子数组最多有一个元素,所以已经排好序。否则,分解步骤简单地计算一个下标q,将A[p,r]分成两个子数组A[p,q]和A[q+1,r],前者包含[n/2]个元素,后者包含[n/2]个元素。

Merge_sort(A,p,r):
if p < r
   q = (p+r)/2
   Merge_sort(A,p,q)
   Merge_sort(A,q+1,r)
   Merge(A,p,q,r)

为了排序整个序列A=(A[0],A[1],...,A[n]),我们执行初始调用Merge_sort(A,0,A.length),这里再次有A.length = n。图2-4自底向上地说明了当n为2的幂时该过程的操作。算法由以下操作组成:合并只含1项的序列对形成长度为2的排好序的序列,合并长度为2的序列对形成长度为4的排好序的序列,依此下去,直到长度为n/2的两个序列被合并最终形成长度为n的排好序的序列。

Java分治归并排序算法实例详解

3、Java代码实现

public class Merge_sort_test {
  public static void Merge(int[] A,int p,int q,int r){
    int[] tmp = new int[r-p+1];//声明一个临时数组,长度为要归并数组的长度
    int i = p;  //记住左边数组第一个元素的下标
    int j = q+1; //记住右边数组第一个元素的下标
    int k = 0;
    while(i <= q && j <= r){
      //左边数组元素和右边数组元素比较,把小的元素赋给临时数组
      if(A[i] <= A[j]){
        tmp[k++] = A[i++];
      }
      else{
        tmp[k++] = A[j++];
      }
    }
    //把左边剩余的数组元素赋给临时数组
    while(i <= q){
      tmp[k++] = A[i++];
    }
    //把右边剩余的数组元素赋给临时数组
    while(j <= r){
      tmp[k++] = A[j++];
    }
    //用临时数组元素覆盖原数组元素
    for(int k2 = 0;k2 < tmp.length;k2++){
      A[k2+p] = tmp[k2];
    }
  }
  public static void/*int[]*/ Merge_sort(int[] A,int p,int r){
    int q = (p+r)/2;
    if(p < r){
      //递归调用
      Merge_sort(A,p,q);
      Merge_sort(A,q + 1,r);
      //归并排序数据元素
      Merge(A,p,q,r);
    }
    //return A;
  }
  public static void main(String[] args) {
    //
    int[] A = {5,2,4,7,1,3,2,6};
    System.out.println("原始数据: ");
    for(int i = 0;i < A.length;i++){
      System.out.print(A[i] + " ");
    }
    System.out.println();
    Merge_sort(A,0,A.length -1);
    System.out.println("输出结果: ");
    for(int i = 0;i < A.length;i++){
      System.out.print(A[i] + " ");
    }
  }
}
Python 相关文章推荐
python使用any判断一个对象是否为空的方法
Nov 19 Python
Python标准库之多进程(multiprocessing包)介绍
Nov 25 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
Apr 28 Python
python爬虫实现教程转换成 PDF 电子书
Feb 19 Python
python实现m3u8格式转换为mp4视频格式
Feb 28 Python
python书籍信息爬虫实例
Mar 19 Python
Python编程中flask的简介与简单使用
Dec 28 Python
python 计算平均平方误差(MSE)的实例
Jun 29 Python
浅谈Python中re.match()和re.search()的使用及区别
Apr 14 Python
Anaconda+vscode+pytorch环境搭建过程详解
May 25 Python
Python图片检索之以图搜图
May 31 Python
Python连续赋值需要注意的一些问题
Jun 03 Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
Dec 12 #Python
Python数据结构与算法之图的基本实现及迭代器实例详解
Dec 12 #Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 #Python
你真的了解Python的random模块吗?
Dec 12 #Python
Python判断两个对象相等的原理
Dec 12 #Python
浅谈Django REST Framework限速
Dec 12 #Python
Django admin美化插件suit使用示例
Dec 12 #Python
You might like
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
PHP中创建空文件的代码[file_put_contents vs touch]
2012/01/20 PHP
php检测数组长度函数sizeof与count用法
2014/11/17 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
纯js实现的论坛常用的运行代码的效果
2008/07/15 Javascript
&amp;lt;script defer&amp;gt; defer 是什么意思
2009/05/10 Javascript
IE innerHTML,outerHTML所引起的问题
2009/06/04 Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
2010/04/09 Javascript
js写一个弹出层并锁屏效果实现代码
2012/12/07 Javascript
E3 tree 1.6在Firefox下显示问题的修复方法
2013/01/30 Javascript
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
2017/09/22 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
2019/03/28 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
Node.js从字符串生成文件流的实现方法
2019/08/18 Javascript
js实现点击上传图片并设为模糊背景
2020/08/02 Javascript
编写同时兼容Python2.x与Python3.x版本的代码的几个示例
2015/03/30 Python
Python中threading模块join函数用法实例分析
2015/06/04 Python
Python使用pyh生成HTML文档的方法示例
2018/03/10 Python
python实时监控cpu小工具
2018/06/21 Python
python多进程控制学习小结
2018/10/31 Python
python 顺时针打印矩阵的超简洁代码
2018/11/14 Python
python常用库之NumPy和sklearn入门
2019/07/11 Python
Python数据可视化实现正态分布(高斯分布)
2019/08/21 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
详解webapp页面滚动卡顿的解决办法
2018/12/26 HTML / CSS
幼儿园爱国卫生月活动总结
2014/06/30 职场文书
行政工作试用期自我评价
2014/09/14 职场文书
合作协议书模板2014
2014/09/26 职场文书
同学聚会通知书
2015/04/20 职场文书
2015暑期社会实践个人总结
2015/07/13 职场文书
zabbix配置nginx监控的实现
2022/05/25 Servers