资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

归并排序Java代码递归 归并排序的代码

java归并排序

.example-btn{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.example-btn:hover{color:#fff;background-color:#47a447;border-color:#398439}.example-btn:active{background-image:none}div.example{width:98%;color:#000;background-color:#f6f4f0;background-color:#d0e69c;background-color:#dcecb5;background-color:#e5eecc;margin:0 0 5px 0;padding:5px;border:1px solid #d4d4d4;background-image:-webkit-linear-gradient(#fff,#e5eecc 100px);background-image:linear-gradient(#fff,#e5eecc 100px)}div.example_code{line-height:1.4em;width:98%;background-color:#fff;padding:5px;border:1px solid #d4d4d4;font-size:110%;font-family:Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;word-break:break-all;word-wrap:break-word}div.example_result{background-color:#fff;padding:4px;border:1px solid #d4d4d4;width:98%}div.code{width:98%;border:1px solid #d4d4d4;background-color:#f6f4f0;color:#444;padding:5px;margin:0}div.code div{font-size:110%}div.code div,div.code p,div.example_code p{font-family:"courier new"}pre{margin:15px auto;font:12px/20px Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;border:1px solid #ddd;border-left-width:4px;padding:10px 15px} 排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。以下是归并排序算法:

创新互联建站是一家集网站建设,宜秀企业网站建设,宜秀品牌网站建设,网站定制,宜秀网站建设报价,网络营销,网络优化,宜秀网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法); 自下而上的迭代;

在《数据结构与算法 JavaScript 描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为:

However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle.

然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。

说实话,我不太理解这句话。意思是 JavaScript 编译器内存太小,递归太深容易造成内存溢出吗?还望有大神能够指教。

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。

2. 算法步骤

申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

设定两个指针,最初位置分别为两个已经排序序列的起始位置;

比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

重复步骤 3 直到某一指针达到序列尾;

将另一序列剩下的所有元素直接复制到合并序列尾。

3. 动图演示

代码实现 JavaScript 实例 function mergeSort ( arr ) {   // 采用自上而下的递归方法

var len = arr. length ;

if ( len

java实现归并排序问题

public void mySort(int low,int high){

int lo=low;

int hi=high;

if (lo=hi) {

return;

}else{

boolean flag=false;

while (lohi) {

if (arrs[lo]arrs[hi]) {

int temp=arrs[lo];

arrs[lo]=arrs[hi];

arrs[hi]=temp;

flag=!flag;

}else{

if (flag) {

lo++;

}else{

hi--;

}

}

}

lo--;

hi++;

mySort(low,lo);

mySort(hi,high);

}

}

这里是递归加二分法(排序的方法) 希望能帮到你!!望~~点赞

归并排序-merge递归

用到递归的思想

分成两半进行排序,把结果进行合并(merge),再分成两半进行排序,一直这样递归下去。

时间和空间消耗比较大。每一次函数调用都需要在内存栈中分配空间以保存参数,返回地址以及临时变量,而且往栈里面压入数据和弹出都需要时间。

要注意basecase,终止条件

平均,最好,最坏 O(N*log2N)

不断分成两半(分的次数就是对数log2N, 每次又是N 所以就是N*log2N)。

空间复杂度

O(N)

稳定, Java对象的排序使用mergesort. 改进版叫TimSort.

JAVA归并排序算法,有两行代码看不懂

以var a = [4,2,6,3,1,9,5,7,8,0];为例子。

1.希尔排序。 希尔排序是在插入排序上面做的升级。是先跟距离较远的进行比较的一些方法。

function shellsort(arr){ var i,k,j,len=arr.length,gap = Math.ceil(len/2),temp; while(gap0){ for (var k = 0; k gap; k++) { var tagArr = []; tagArr.push(arr[k]) for (i = k+gap; i len; i=i+gap) { temp = arr[i]; tagArr.push(temp); for (j=i-gap; j -1; j=j-gap) { if(arr[j]temp){ arr[j+gap] = arr[j]; }else{ break; } } arr[j+gap] = temp; } console.log(tagArr,"gap:"+gap);//输出当前进行插入排序的数组。 console.log(arr);//输出此轮排序后的数组。 } gap = parseInt(gap/2); } return arr; }

过程输出:

[4, 9] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [2, 5] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [6, 7] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [3, 8] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [1, 0] "gap:5" [4, 2, 6, 3, 0, 9, 5, 7, 8, 1] [4, 6, 0, 5, 8] "gap:2" [0, 2, 4, 3, 5, 9, 6, 7, 8, 1] [2, 3, 9, 7, 1] "gap:2" [0, 1, 4, 2, 5, 3, 6, 7, 8, 9] [0, 1, 4, 2, 5, 3, 6, 7, 8, 9] "gap:1" [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

由输出可以看到。第一轮间隔为5。依次对这些间隔的数组插入排序。

间隔为5:

[4, 9] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [2, 5] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [6, 7] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [3, 8] "gap:5" [4, 2, 6, 3, 1, 9, 5, 7, 8, 0] [1, 0] "gap:5" [4, 2, 6, 3, 0, 9, 5, 7, 8, 1] [4, 6, 0, 5, 8] "gap:2" [0, 2, 4, 3, 5, 9, 6, 7, 8, 1] [2, 3, 9, 7, 1] "gap:2" [0, 1, 4, 2, 5, 3, 6, 7, 8, 9] [0, 1, 4, 2, 5, 3, 6, 7, 8, 9] "gap:1" [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

间隔为2:

[4, 2, 6, 3, 0, 9, 5, 7, 8, 1] 4 6 0 5 8 2 3 9 7 1

排序后:

[0, 1, 4, 2, 5, 3, 6, 7, 8, 9]

间隔为1:

排序后:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。

2.快速排序。把一个数组以数组中的某个值为标记。比这个值小的放到数组的左边,比这个值得大的放到数组的右边。然后再递归 对左边和右边的数组进行同样的操作。直到排序完成。通常以数组的第一个值为标记。

代码:

function quickSort(arr){ var len = arr.length,leftArr=[],rightArr=[],tag; if(len2){ return arr; } tag = arr[0]; for(i=1;ilen;i++){ if(arr[i]=tag){ leftArr.push(arr[i]) }else{ rightArr.push(arr[i]); } } return quickSort(leftArr).concat(tag,quickSort(rightArr)); }

3.归并排序。把一系列排好序的子序列合并成一个大的完整有序序列。从最小的单位开始合并。然后再逐步合并合并好的有序数组。最终实现归并排序。

合并两个有序数组的方法:

function subSort(arr1,arr2){ var len1 = arr1.length,len2 = arr2.length,i=0,j=0,arr3=[],bArr1 = arr1.slice(),bArr2 = arr2.slice(); while(bArr1.length!=0 || bArr2.length!=0){ if(bArr1.length == 0){ arr3 = arr3.concat(bArr2); bArr2.length = 0; }else if(bArr2.length == 0){ arr3 = arr3.concat(bArr1); bArr1.length = 0; }else{ if(bArr1[0]=bArr2[0]){ arr3.push(bArr1[0]); bArr1.shift(); }else{ arr3.push(bArr2[0]); bArr2.shift(); } } } return arr3; }

归并排序:

function mergeSort(arr){ var len= arr.length,arrleft=[],arrright =[],gap=1,maxgap=len-1,gapArr=[],glen,n; while(gapmaxgap){ gap = Math.pow(2,n); if(gap=maxgap){ gapArr.push(gap); } n++; } glen = gapArr.length; for (var i = 0; i glen; i++) { gap = gapArr[i]; for (var j = 0; j len; j=j+gap*2) { arrleft = arr.slice(j, j+gap); arrright = arr.slice(j+gap,j+gap*2); console.log("left:"+arrleft,"right:"+arrright); arr = arr.slice(0,j).concat(subSort(arrleft,arrright),arr.slice(j+gap*2)); } } return arr; }

排序[4,2,6,3,1,9,5,7,8,0]输出:

left:4 right:2 left:6 right:3 left:1 right:9 left:5 right:7 left:8 right:0 left:2,4 right:3,6 left:1,9 right:5,7 left:0,8 right: left:2,3,4,6 right:1,5,7,9 left:0,8 right: left:1,2,3,4,5,6,7,9 right:0,8

看出来从最小的单位入手。

第一轮先依次合并相邻元素:4,2; 6,3; 1,9; 5,7; 8,0

合并完成之后变成: [2,4,3,6,1,9,5,7,0,8]

第二轮以2个元素为一个单位进行合并:[2,4],[3,6]; [1,9],[5,7]; [0,8],[];

合并完成之后变成:[2,3,4,6,1,5,7,9,0,8]

第三轮以4个元素为一个单位进行合并:[2,3,4,6],[1,5,7,9]; [0,8],[]

合并完成之后变成: [1,2,3,4,5,6,7,9,0,8];

第四轮以8个元素为一个单位进行合并: [1,2,3,4,5,6,7,9],[0,8];

合并完成。 [0,1,2,3,4,5,6,7,8,9];

怎样使用递归实现归并排序

第一步:先写一个合并两个排序好数组的方法,方法名就叫做merge,如下:

[java] view plain copy

public static void merge(int[] a, int aSize, int[] b, int bSize, int[] c){

int tempA = 0, tempB = 0, tempC = 0;

while(tempA  aSize  tempB  bSize){

if(a[tempA]  b[tempB]){

c[tempC++] = b[tempB++];

}else{

c[tempC++] = a[tempA++];

}

}

while(tempA  aSize){

c[tempC++] = a[tempA++];

}

while(tempB  bSize){

c[tempC++] = b[tempB++];

}

这个方法非常简单,一共有着5个参数(也可以简化为3个参数),其中a,b数组是待合并数组,aSize,bSize是数组长度(这两个参数可以去掉),c为目标数组。主要的流程就是不断的比较a,b数组的大小,然后将较小数据复制进c中。这里面关键的一点就是使用了3个临时变量,用于标志每个数组对应的位置,这样子可以极大简化我们的代码设计。下面是对应的图示过程:

有了这个方法之后,我们就可以开始写归并排序的主体方法了。写主体方法也很简单,思想就是分治算法。

第一步:就是将大数组分成两个小的数组

第二部:排序这两个数组,使用的是递归排序方法,也就是自己调用自己

第三部:调用上面的合并方法合并起来即可

代码非常简单,直接贴上

[java] view plain copy

public class TowersApp{

public static void main(String[] args){

int[] a = {1,1,0,1,1,5,3};

mergeSort(a);

for(int i=0; ia.length; i++){

System.out.print(a[i]);

}

}

public static void mergeSort(int[] source){

//递归出口

if(source.length == 1) return;

//将大数组分成两个小数组

int middle = source.length / 2;

int[] left = new int[middle];

for(int i=0; imiddle; i++){

left[i] = source[i];

}

int[] right = new int[source.length - middle];

for(int i=middle; isource.length; i++){

right[i-middle] = source[i];

}

//对数据进行排序(这里使用递归排序)

mergeSort(left);

mergeSort(right);

//合并排序好的数据

merge(left, left.length, right, right.length, source);

}

public static void merge(int[] a, int aSize, int[] b, int bSize, int[] c){

int tempA = 0, tempB = 0, tempC = 0;

while(tempA  aSize  tempB  bSize){

if(a[tempA]  b[tempB]){

c[tempC++] = b[tempB++];

}else{

c[tempC++] = a[tempA++];

}

}

while(tempA  aSize){

c[tempC++] = a[tempA++];

}

while(tempB  bSize){

c[tempC++] = b[tempB++];

}

}

}

总结:要记住归并排序算法的核心核心思想:分而治之。

java中归并排序

1、归并排序实现:

public static void main(String[] args) {

int a[]={1,8,2,6,5,4};

int[] arr= sort(a,0,a.length-1);

for(int rr=0;rr=5;rr++)

System.out.printf("%d\t", arr[rr]);

System.out.printf("\n");

}

public static int[] sort(int[] a,int low,int high){

int mid = (low+high)/2;

if(lowhigh){

sort(a,low,mid);

sort(a,mid+1,high);

//左右归并

merge(a,low,mid,high);

}

return a;

}

public static void merge(int[] a, int low, int mid, int high) {

int[] temp = new int[high-low+1];

int i= low;

int j = mid+1;

int k=0;

// 把较小的数先移到新数组中

while(i=mid  j=high){

if(a[i]a[j]){

temp[k++] = a[i++];

}else{

temp[k++] = a[j++];

}

}

// 把左边剩余的数移入数组 

while(i=mid){

temp[k++] = a[i++];

}

// 把右边边剩余的数移入数组

while(j=high){

temp[k++] = a[j++];

}

// 把新数组中的数覆盖nums数组

for(int x=0;xtemp.length;x++){

a[x+low] = temp[x];

}

}

2、简单的数组排序

public static void main(String[] args) {

int a[]={1,8,2,6,5,4};

Arrays.sort(a);

for(int rr=0;rr=5;rr++)

System.out.printf("%d\t", a[rr]);

System.out.printf("\n");

}


网页名称:归并排序Java代码递归 归并排序的代码
转载注明:http://cdkjz.cn/article/doscjjc.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220