分治归并排序算法——Java实现
来源:互联网 发布:qq邮箱申请淘宝账号 编辑:程序博客网 时间:2024/06/05 11:34
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 = pj = q+1while i <= q && j <= r if A[i] <= A[j]tmp[k++] = A[i++]; elsetmp[k++] = A[j++]; while i <= qtmp[k++] = A[i++]; while j <= rtmp[k++] = A[j++]; for k2 = 0 to tmp.lengthA[k2+p] = tmp[k2];
现在我们可以把过程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的排好序的序列。
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] + " ");}}}
- 分治归并排序算法——Java实现
- 分治算法——快速排序、归并排序算法(Java实现)
- 分治算法实现归并排序
- 分治法算法——归并排序
- 算法学习之路:分治策略-归并排序-java实现
- 【算法】分治法之归并排序实现
- 分治算法——快速排序,归并排序
- 分治算法——归并排序与快速排序
- 分治算法--归并排序
- 分治算法-归并排序
- 分治算法-归并排序
- 算法--分治归并排序
- 归并排序-分治算法
- 分治算法---归并排序
- 分治归并——排序
- 分治——归并排序
- 分治法—归并排序
- 分治策略—归并排序
- 关于js面向对象
- 计算几何模板
- JS闭包测试
- 北斗模块学习之初
- LNMP基于fastcgi实现nginx,php,mysql的分离
- 分治归并排序算法——Java实现
- C++ 之 over-eager evaluation 超前评估
- linux 密码用小键盘输入不正确
- Hadoop YARN资源隔离技术
- Android 源码下编译APK
- 12-7java面向对象之this关键字的说明
- 告别罗永浩,锤子手机未来可期
- U-boot启动流程——eloader
- c#使用皮肤引擎更新自己的界面