归并排序
对数列进行分组比较,最后递归合并在一起,赋值给原数组
用到最小位置,最大位置,中间位置来划分,很有创造性的一个排序方法。
对指针或索引之类的要加深理解,考虑移动方向和临界状态,满足特殊情况,一定可以满足一般情况。
package com.bjsxt.Sort;
import java.util.Arrays;
//归并排序
public class MergeSort {
public static void main(String[] args){
int[] arr = new int[]{1,3,5,2,4,6,8,10,0};
System.out.println(Arrays.toString(arr));
mergeSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
//归并排序
public static void mergeSort(int[] arr,int low,int high){
int middle=(high+low)/2;
if(low<high){
//处理左边
mergeSort(arr,low,middle);
//处理右边
mergeSort(arr,middle+1,high);
//归并
merge(arr,low,middle,high);
}
}
public static void merge(int[] arr,int low,int middle, int high){
//用于储存归并后的临时数组
int[] temp = new int[high-low+1];
//记录第一个数组中需要遍历的下标
int i = low;
//记录第二个数组中需要遍历的下标
int j = middle +1;
//用于记录临时数组中存放的下标
int index = 0;
//遍历两个数组取出小的数字,放入临时数组中
while(i<=middle&&j<=high){
//第一个数组的数据更小
if(arr[i]<=arr[j]){
//把小的数据放入临时数组中
temp[index]=arr[i];
//让下标向后移一位
i++;
}else{
temp[index]=arr[j];
j++;
}
index++;
}
//处理多余的数据
while(j<=high){
temp[index]=arr[j];
j++;
index++;
}
while(i<=middle){
temp[index]=arr[i];
i++;
index++;
}
//把临时数组中的数据重新存入原数据
for(int k=0;k<temp.length;k++){
arr[k+low]=temp[k];
}
}
}
执行结果
[1, 3, 5, 2, 4, 6, 8, 10, 0]
[0, 1, 2, 3, 4, 5, 6, 8, 10]
百度后的java实现归并排序
package com.bjsxt.Sort;
import java.util.Arrays;
public class test {
// private static long sum = 0;
/**
* * <pre>
* * 二路归并
* * 原理:将两个有序表合并和一个有序表
* * </pre>
* *
* * @param a
* * @param s
* * 第一个有序表的起始下标
* * @param m
* * 第二个有序表的起始下标
* * @param t
* * 第二个有序表的结束下标
* *
*/
private static void merge(int[] a, int s, int m, int t) {
int[] tmp = new int[t - s + 1];
int i = s, j = m, k = 0;
while (i < m && j <= t) {
if (a[i] <= a[j]) {
tmp[k] = a[i];
k++;
i++;
} else {
tmp[k] = a[j];
j++;
k++;
}
}
while (i < m) {
tmp[k] = a[i];
i++;
k++;
}
while (j <= t) {
tmp[k] = a[j];
j++;
k++;
}
System.arraycopy(tmp, 0, a, s, tmp.length);
}
/**
* *
* * @param a
* * @param s
* * @param len
* * 每次归并的有序集合的长度
*/
public static void mergeSort(int[] a, int s, int len) {
int size = a.length;
int mid = size / (len << 1);
int c = size & ((len << 1) - 1);
// -------归并到只剩一个有序集合的时候结束算法-------//
if (mid == 0)
return;
// ------进行一趟归并排序-------//
for (int i = 0; i < mid; ++i) {
s = i * 2 * len;
merge(a, s, s + len, (len << 1) + s - 1);
}
// -------将剩下的数和倒数一个有序集合归并-------//
if (c != 0)
merge(a, size - c - 2 * len, size - c, size - 1);
// -------递归执行下一趟归并排序------//
mergeSort(a, 0, 2 * len);
}
public static void main(String[] args) {
int[] a = new int[]{4, 3, 6, 1, 2, 5};
System.out.println(Arrays.toString(a));
mergeSort(a, 0, 1);
for (int i = 0; i < a.length; ++i) {
System.out.print(a[i] + " ");
}
}
}
执行结果
[4, 3, 6, 1, 2, 5]
1 2 3 4 5 6