归并排序算法剖析,附java源代码

思路:

所谓的归并排序就是将二分查找和动态规划相结合的算法。

假设当前为顺序排序

通过对m个元素的数组进行排序,排序到n次,将产生n个有序数组,遍历第n+1次,通过二分查找在n个有序数组中找到比当前m[n+1]的数最左侧的数【2分查找】,记录该元素位置知道遍历m次整个数组都是有序的【动态规划】

归并排序过程样例:

初始数组

[3,6,8,7,4,1,5,11,9,39,21,34,52,12,32]

3,6,8,7,4,1,5,11,9,39,21,34,52,12,32,第1次排序;

比较过程 比较开始---[compare,mid0|,3:6]----比较结束.i:1,mid:0,low:1,high:0...

本次比较不需要位移

当次数组值为:3,6,8,7,4,1,5,11,9,39,21,34,52,12,32,

3,6,8,7,4,1,5,11,9,39,21,34,52,12,32,第2次排序;

比较过程 比较开始---[compare,mid0|,3:8][compare,mid1|,6:8]----比较结束.i:2,mid:1,low:2,high:1...

本次比较不需要位移

当次数组值为:3,6,8,7,4,1,5,11,9,39,21,34,52,12,32,

3,6,8,7,4,1,5,11,9,39,21,34,52,12,32,第3次排序;

比较过程 比较开始---[compare,mid1|,6:7][compare,mid2|,8:7]----比较结束.i:3,mid:2,low:2,high:1...

开始进行移动:从下标2开始移动至3结束move,

当次数组值为:3,6,7,8,4,1,5,11,9,39,21,34,52,12,32,

3,6,7,8,4,1,5,11,9,39,21,34,52,12,32,第4次排序;

比较过程 比较开始---[compare,mid1|,6:4][compare,mid0|,3:4]----比较结束.i:4,mid:0,low:1,high:0...

开始进行移动:从下标1开始移动至4结束move,move,move,

当次数组值为:3,4,6,7,8,1,5,11,9,39,21,34,52,12,32,

3,4,6,7,8,1,5,11,9,39,21,34,52,12,32,第5次排序;

比较过程 比较开始---[compare,mid2|,6:1][compare,mid0|,3:1]----比较结束.i:5,mid:0,low:0,high:-1...

开始进行移动:从下标0开始移动至5结束move,move,move,move,move,

当次数组值为:1,3,4,6,7,8,5,11,9,39,21,34,52,12,32,

1,3,4,6,7,8,5,11,9,39,21,34,52,12,32,第6次排序;

比较过程 比较开始---[compare,mid2|,4:5][compare,mid4|,7:5][compare,mid3|,6:5]----比较结束.i:6,mid:3,low:3,high:2...

开始进行移动:从下标3开始移动至6结束move,move,move,

当次数组值为:1,3,4,5,6,7,8,11,9,39,21,34,52,12,32,

1,3,4,5,6,7,8,11,9,39,21,34,52,12,32,第7次排序;

比较过程 比较开始---[compare,mid3|,5:11][compare,mid5|,7:11][compare,mid6|,8:11]----比较结束.i:7,mid:6,low:7,high:6...

本次比较不需要位移

当次数组值为:1,3,4,5,6,7,8,11,9,39,21,34,52,12,32,

1,3,4,5,6,7,8,11,9,39,21,34,52,12,32,第8次排序;

比较过程 比较开始---[compare,mid3|,5:9][compare,mid5|,7:9][compare,mid6|,8:9][compare,mid7|,11:9]----比较结束.i:8,mid:7,low:7,high:6...

开始进行移动:从下标7开始移动至8结束move,

当次数组值为:1,3,4,5,6,7,8,9,11,39,21,34,52,12,32,

1,3,4,5,6,7,8,9,11,39,21,34,52,12,32,第9次排序;

比较过程 比较开始---[compare,mid4|,6:39][compare,mid6|,8:39][compare,mid7|,9:39][compare,mid8|,11:39]----比较结束.i:9,mid:8,low:9,high:8...

本次比较不需要位移

当次数组值为:1,3,4,5,6,7,8,9,11,39,21,34,52,12,32,

1,3,4,5,6,7,8,9,11,39,21,34,52,12,32,第10次排序;

比较过程 比较开始---[compare,mid4|,6:21][compare,mid7|,9:21][compare,mid8|,11:21][compare,mid9|,39:21]----比较结束.i:10,mid:9,low:9,high:8...

开始进行移动:从下标9开始移动至10结束move,

当次数组值为:1,3,4,5,6,7,8,9,11,21,39,34,52,12,32,

1,3,4,5,6,7,8,9,11,21,39,34,52,12,32,第11次排序;

比较过程 比较开始---[compare,mid5|,7:34][compare,mid8|,11:34][compare,mid9|,21:34][compare,mid10|,39:34]----比较结束.i:11,mid:10,low:10,high:9...

开始进行移动:从下标10开始移动至11结束move,

当次数组值为:1,3,4,5,6,7,8,9,11,21,34,39,52,12,32,

1,3,4,5,6,7,8,9,11,21,34,39,52,12,32,第12次排序;

比较过程 比较开始---[compare,mid5|,7:52][compare,mid8|,11:52][compare,mid10|,34:52][compare,mid11|,39:52]----比较结束.i:12,mid:11,low:12,high:11...

本次比较不需要位移

当次数组值为:1,3,4,5,6,7,8,9,11,21,34,39,52,12,32,

1,3,4,5,6,7,8,9,11,21,34,39,52,12,32,第13次排序;

比较过程 比较开始---[compare,mid6|,8:12][compare,mid9|,21:12][compare,mid7|,9:12][compare,mid8|,11:12]----比较结束.i:13,mid:8,low:9,high:8...

开始进行移动:从下标9开始移动至13结束move,move,move,move,

当次数组值为:1,3,4,5,6,7,8,9,11,12,21,34,39,52,32,

1,3,4,5,6,7,8,9,11,12,21,34,39,52,32,第14次排序;

比较过程 比较开始---[compare,mid6|,8:32][compare,mid10|,21:32][compare,mid12|,39:32][compare,mid11|,34:32]----比较结束.i:14,mid:11,low:11,high:10...

开始进行移动:从下标11开始移动至14结束move,move,move,

当次数组值为:1,3,4,5,6,7,8,9,11,12,21,32,34,39,52,

代码样例:

package com.qunar;

 

import java.util.Collection;

import java.util.Collections;

import java.util.HashMap;

import java.util.List;

 

/**

* Created by yubin.qi on 2015/4/29.

*/

public class DichotomySort {

 

// 算法思想简单描述: 在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们 中间的那个元素比,如果小,则对前半再进行折半,否则对后半 进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间 的所有元素后移,再把第i个元素放在目标位置上。

// 二分法排序最重要的一个步骤就是查找要插入元素的位置,也就是要在哪一个位置上放我们要准备排序的这个元素。

// 当我们查找到位置以后就很好说了,和插入排序一样,将这个位置以后的所有元素都向后移动一位。这样就实现了二分法排序。

//   然后是怎么查找着一个位置呢,就是不断的比较已排序的序列中的中间元素和要排序元素,如果大于的话,说明这个要排

// 序的元素在已排序序列中点之前的序列。

 

public static void main(String args[]) {

 

int[] is = new int[]{3, 6, 8, 7, 4, 1, 5, 11, 9, 39, 21, 34, 52, 12, 32};

 

DichotomySort(is);

 

for (int temp : is) {

System.out.println(temp);

}

 

}

 

 

//

 

public static void DichotomySort(int[] array) {

 

int i, j;

int low, high, mid;

mid = 0;

int temp;

for (i = 1; i < array.length; i++) {

 

temp = array[i];

low = 0;

high = i - 1;

for (int temp1 : array) {

System.out.print(temp1 + ",");

 

}

//该算法的精髓是确定需要移动几位到中间值 每次排序能保证中间值之前是有序的所以考虑当前值移动几位到中间值

//如果起始游标 小于或者等于结束游标时一致循环直到结束游标大于起始游标

//例子

//------>起------<结 (循环)

//------<结>起------ (完毕)

System.out.println("第" + (i) + "次排序;");

boolean x = true;

while (low <= high) {

if (x) {

x = false;

System.out.print("比较过程 比较开始---");

}

 

//每次该变量均会在上一次折半的基础上再次折半

mid = (low + high) / 2;

System.out.print("[compare,mid" + mid + "|," + array[mid] + ":" + temp + "]");

 

if (array[mid] > temp) {

//如果当前值大于需要比对的值,结束游标值在中值这块往前位移,找到比该值更小的值

high = mid - 1;

} else {

//如果当前值小于或者等于需要比对的值,起始游标值在中值这块往后挪动一位

low = mid + 1;

}

}

 

System.out.print("----比较结束");

 

System.out.print(".i:" + i + ",mid:" + mid + ",low:" + low + ",high:" + high + "...\r\n");

if (high == i - 1)

System.out.print("本次比较不需要位移");

else

System.out.print("开始进行移动:从下标" + (high+1) + "开始移动至下标"+i+"结束");

for (j = i - 1; j > high; j--) {

System.out.print("move,");

array[j + 1] = array[j];

}

 

 

array[high + 1] = temp;

System.out.println();

System.out.print("当次数组值为:");

for (int temp1 : array) {

System.out.print(temp1 + ",");

 

}

System.out.println();

System.out.println();

 

}

 

}

 

}

时间: 2024-11-05 04:29:26

归并排序算法剖析,附java源代码的相关文章

归并排序算法--java

归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))

【Java集合源代码剖析】LinkedList源代码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/35787253 您好.我正在參加CSDN博文大赛.假设您喜欢我的文章,希望您能帮我投一票,谢谢. 投票地址:articleid=35568011" style="color: rgb(106, 57, 6); text-decoration: none; ">http://vote.blog.csdn.net/Article/Details?articleid=3

【Java集合源代码剖析】HashMap源代码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 您好,我正在參加CSDN博文大赛,假设您喜欢我的文章.希望您能帮我投一票.谢谢! 投票地址:http://vote.blog.csdn.net/Article/Details? articleid=35568011 HashMap简单介绍 HashMap是基于哈希表实现的,每个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,相同会自己

必须知道的八大种排序算法【java实现】(三) 归并排序算法、堆排序算法详解

一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序示例: 合并方法: 设r[i-n]由两个有序子表r[i-m]和r[m+1-n]组成,两个子表长度分别为n-i +1.n-m. j=m+1:k=i:i=i; //置两个子表的起始下标及辅助数组的起始下标 若i>m 或j>n,转⑷ //其中一个子表已合并完,比较选取结束 //选取r[i]和r[j]

Java算法学习-----------------归并排序算法

将数组中的相邻元素两两配对,用归并算法进行排序,构成n/2组长度为2的排好序的子数组段,然后再将其排成长度为4的子数组段,如此继续下去直到整个数组排好序. 按照此思想,消除递归后的归并排序算法(伪代码)如下: public class MergeSort { public static void mergeSort(Comparable[]a) { Comparable[]b=new Comparable[a.length]; int s=1; while (s<a.length) { merg

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明文是yanzi1225627,得到MD5加密后的字符串是:14F2AE15259E2C276A095E7394DA0CA9  但不能由后面一大串倒推出yanzi1225627.因此可以用来存储用户输入的密码在服务器上.现在下载文件校验文件是否中途被篡改也是用的它,原理参见:http://blog.c

递归分治算法(一)-归并排序算法

前言: 分治法是一种算法设计思想,所谓分治,意为分而治之,是指将一个难以直接解决的大问题,递归的分割成一些规模的较小的问题,以便逐个解决.采用分治法设计的算法通常用到递归算法来实现,故标题为递归分治. 归并排序算法 归并就是将两个或两个以上的有序表合并成一个新的有序表.归并排序就是将无序的待排序的序列分解成若干个有序的子序列,并把有序子序列合并为整体有序序列的过程.一般分为2-路归并排序和多路归并排序. 他的大概流程如下图: 我们来看看java代码怎么写的: package guibing; /

中国象棋V2:Java源代码、毕业设计等所有文档,已经全部提交到CSDN-Code平台

下载地址:https://code.csdn.net/FansUnion/chinesechess-v2 主要内容:Java源代码.毕业设计.API文档.声音图片等资源.Demo截图等一切的一切. 2012年就已经把所有资料上传到CSDN下载频道了,结果总是有网友反馈无法下载或者找不到源码,今天终于解决了这个"历史遗留问题". 如果,把大学阶段完成的中国象棋,一切资料全部分享,上传到CSDN-Code平台,还有网友说找不到源码,那真心不能怪我了. 特别说明: 1.我不想再多费口舌去过多

归并排序算法实现

关于归并排序算法的思想,网上有很多介绍,这里不再解释,这里提供了一个Java类,读者可以把类潜入到自己的程序中,直接调用,免去了重新编写归并排序的过程. 具体的Java代码如下: 1 import java.util.*; 2 class Mergesort { 3 4 public static void merge(int a[],int start,int mid,int end){ //归并方法 5 int b[]=new int[a.length]; //借助中间数组,用来暂存排序结果