归并排序:两个有序的数组合并成一个数组,指针I为第一个数组的开头,指针J为第二个数组的开头,比较两个元素,选择相对小的元素放入到合并空间,并移动指针到下一个
分成两个数组,两个数组都是有序的
比较大小2>1,1移到新数组里面,J指针往后一格
比较大小3>2,2移到新数组里面,I指针往后一格
比较大小4>3,3移到新数组里面,J指针往后一格
比较大小9>4,4移到新数组里面,I指针往后一格
比较大小9>5,5移到新数组里面
只剩下数字9,放上去
一般情况下,数组都不是有序的,因此程序一般有递归把数组分到最小,然后用上面两个有序数组合并到一个数组。
如:
现在从下往上,从每个小数组里排序合并数组排序(新数组)(从下往上看)
代码
假如两个数组是有序的
245 139
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{2,4,5};
int[] ints2= new int[]{1,3,9};
//合并成新数组
int[] newInts = new int[ints1.length+ints2.length];
int i=0,j=0;
int p=0;
//第一想的,如图上第一第二张
//比较大小2>1,1移到新数组里面,J指针往后一格
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[0];
j++;
}else{
newInts[p++]= ints1[0];
i++;
}
print(newInts);
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
100000
2放上去,继续走
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{2,4,5};
int[] ints2= new int[]{1,3,9};
//合并成新数组
int[] newInts = new int[ints1.length+ints2.length];
int i=0,j=0;
int p=0;
//第一想的,如图上第一第二张
//比较大小2>1,1移到新数组里面,J指针往后一格
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[0];
j++;
}else{
newInts[p++]= ints1[0];
i++;
}
//2放上去
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[0];
j++;
}else{
newInts[p++]= ints1[0];
i++;
}
print(newInts);
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
120000
合并代码块
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[0];
j++;
}else{
newInts[p++]= ints1[0];
i++;
}
合并后
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{2,4,5};
int[] ints2= new int[]{1,3,9};
//合并成新数组
int[] newInts = new int[ints1.length+ints2.length];
int i=0,j=0;
int p=0;
//第一想的,如图上第一第二张
//比较大小2>1,1移到新数组里面,J指针往后一格
while(i<ints1.length && j<ints2.length){
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[j];
j++;
}else{
newInts[p++]= ints1[i];
i++;
}
}
print(newInts);
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
123450
修改判断值(临界值),或者添加
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{2,4,5};
int[] ints2= new int[]{1,3,9};
//合并成新数组
int[] newInts = new int[ints1.length+ints2.length];
int i=0,j=0;
int p=0;
//第一想的,如图上第一第二张
//比较大小2>1,1移到新数组里面,J指针往后一格
while(i<ints1.length && j<ints2.length){
if(ints1[i]>ints2[j]){
newInts[p++]= ints2[j];
j++;
}else{
newInts[p++]= ints1[i];
i++;
}
}
//添加最后值
//添加最后值
while(i<=ints1.length-1){
newInts[i]=ints1[i];
i++;
}
while(j<=ints2.length-1){
newInts[p]=ints2[j];
j++;
}
print(newInts);
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
123459
上面是两个有序数组的思维,一般情况下我们针对一个无序数组去排序,先展示下一个无序数组,分开后是有序的,
{1,4,7,8,3,6,9}分成两个后,代码上的指针也要对应的改
1278
369
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{1,4,7,8,3,6,9};
int[] merge = merge(ints1);
print(merge);
}
private static int[] merge(int[] ints1) {
int[] newInts = new int[ints1.length];
int mid = newInts.length/2;
int i=0,j=mid+1;
int p=0;
//第一想的,如图上第一第二张
while(i<mid && j<ints1.length){
if(ints1[i]>=ints1[j]){
newInts[p++]= ints1[j];
j++;
}else{
newInts[p++]= ints1[i];
i++;
}
}
//i指针往右剩下的
while(i<=mid){
newInts[p++]=ints1[i];
i++;
}
//j指针往右剩下的
while(j<=ints1.length-1){
newInts[p]=ints1[j];
j++;
}
return newInts;
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
1346789
代码优化 其实j++,i++可以写在判断里面
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{1,4,7,8,3,6,9};
int[] merge = merge(ints1);
print(merge);
}
private static int[] merge(int[] ints1) {
int[] newInts = new int[ints1.length];
int mid = newInts.length/2;
int i=0,j=mid+1;
int p=0;
//第一想的,如图上第一第二张
while(i<mid && j<ints1.length){
if(ints1[i]>=ints1[j]){
newInts[p++]= ints1[j++];
}else{
newInts[p++]= ints1[i++];
}
}
//添加最后值
while(i<=mid){
newInts[p++]=ints1[i++];
}
while(j<=ints1.length-1){
newInts[p]=ints1[j++];
}
return newInts;
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
针对if else 只有两个判断条件时,改成三目运算符
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{1,4,7,8,3,6,9};
int[] merge = merge(ints1);
print(merge);
}
private static int[] merge(int[] ints1) {
int[] newInts = new int[ints1.length];
int mid = newInts.length/2;
int i=0,j=mid+1;
int p=0;
//第一想的,如图上第一第二张
while(i<mid && j<ints1.length){
newInts[p++]=ints1[i]>=ints1[j]?ints1[j++]:ints1[i++];
/*if(ints1[i]>=ints1[j]){
newInts[p++]= ints1[j++];
}else{
newInts[p++]= ints1[i++];
}*/
}
//添加最后值
while(i<=mid){
newInts[p++]=ints1[i++];
}
while(j<=ints1.length-1){
newInts[p]=ints1[j++];
}
return newInts;
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
因为要使用递归的排序,代码中merge并不灵活,因为最终往下分成一块一块,然后合并,所以merge这里缺少左指针,右指针,右边界
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] ints1= new int[]{1,4,7,8,3,6,9};
int[] merge = merge(ints1,0,4,6);
print(merge);
}
private static int[] merge(int[] ints1,int left,int right,int rightBorder) {
//改变数值
int[] newInts = new int[rightBorder-left+1];
int mid = right;
int i=left;
int j=right;
int p=0;
while(i<=mid && j<rightBorder){
newInts[p++]=ints1[i]>=ints1[j]?ints1[j++]:ints1[i++];
}
//添加最后值
while(i<mid){
newInts[p++]=ints1[i++];
}
while(j<=rightBorder){
newInts[p]=ints1[j++];
}
return newInts;
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
最终代码
package com.my;
public class MergeSort {
public static void main(String[] args) {
int[] arrs= new int[]{1,4,7,8,3,6,9};
sort(arrs,0,arrs.length-1);
print(arrs);
}
private static void sort(int[] arrs,int L,int R) {
//结束条件
if(L==R) return;
//分成两半
int mid = L+(R-L)/2;
//左边排序,递归
sort(arrs,L,mid);
//右边排序,递归
sort(arrs,mid+1,R);
//合并
merge(arrs,L,mid+1,R);
}
//假定排好序的情况下合并
private static void merge(int[] arrs,int left,int right,int rightBorder) {
//改变数值
int[] newInts = new int[rightBorder-left+1];
int mid = right-1;
int i=left;
int j=right;
int p=0;
while(i<=mid && j<=rightBorder){
newInts[p++]=arrs[i]>arrs[j]?arrs[j++]:arrs[i++];
}
//添加最后值
while(i<=mid){
newInts[p++]=arrs[i++];
}
while(j<=rightBorder){
newInts[p++]=arrs[j++];
}
//写回原先
for(int m=0;m<newInts.length;m++) arrs[left+m] = newInts[m];
}
public static void print(int[] ints){
for(int i:ints){
System.out.print(i);
}
}
}
总结
要有递归的思想,而且要注意边界值