归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and
Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使
子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并
非递归方法:
- 将无序数组按一组1个,2个,4个…分 ;使用循环 递增条件为2*n;
- 当一组按照一个分时,进行 合并,存放入新的数组,这个过程一直循环到 最后一组为数组的所有值
- 将最终合并的数组按照顺序 拷贝给 无序数组
程序实现:
public static void mergeSort(int[] array) {
for (int gap = 1; gap < array.length; gap*=2) {
merge1(array,gap);
}
}
//合并方法
public static void merge1(int[] array,int gap) {
//新的数组
int[] tmp = new int[array.length];
//新数组的下表
int i = 0;
// 每次分组之后的 无序段下表代表
int s1 = 0;
int e1 = s1+gap-1;
int s2 = e1+1;
int e2 = (s2+gap-1 >= array.length) ? array.length-1 : s2+gap-1;
// 这个循环是有两段无序的都存在时
while (s2 < array.length) {
while (s1 <= e1 && s2 <= e2) {
//判断比较,并存入新的数组
if(array[s1] <= array[s2]) {
tmp[i++] = array[s1++];
} else {
tmp[i++] = array[s2++];
}
}
while(s1 <= e1) {
tmp[i++] = array[s1++];
}
while(s2 <= e2) {
tmp[i++] = array[s2++];
}
//重新s1,e1,s2,e2 位置
s1 = e2+1;
e1 = s1+gap-1;
s2 = e1+1;
e2 = (s2+gap-1 >= array.length) ? array.length-1 : s2+gap-1;
}
//判断s1是否有数据 代表 只有一组无序数据段
while(s1 < array.length) {
tmp[i++] = array[s1++];
}
//拷贝tmp到array
for (int j = 0; j < tmp.length; j++) {
array[j] = tmp[j];
}
}
递归版本
- 递归方法和二叉树类似, 先一分为二,再一直向左递归,知道递归为 每组一个元素时结束,开始合并;
- 合并,比较进行,将较小的放入新的的数组中,两个同时从头开始比较,之后要将较长的数据段之后的所有数据也放入新数组;
- 将合并之后的拷贝入新的数组,因为两个合并完就拷贝一次,所以要注意下表;
程序如下:
public static void mergeSort1(int[] array,int low,int high) {
//终止条件
if(low == high) {
return;
}
int mid = (low+high)/2;
mergeSort1(array,low,mid);
mergeSort1(array,mid+1,high);
//合并
merge(array,low,mid,high);
}
public static void merge(int[] array,int low,int mid,int high){
//s1 s2 代表 需要合并的两段数据的 最开始下标
int s1 = low;
int s2 = mid+1;
int len = high-low+1; //合并完的数组长度
//新的数组
int[] tmp = new int[len];
int i = 0;
while (s1 <= mid && s2 <= high) {
//进行比较 放入新的数组
if(array[s1] <= array[s2]) {
tmp[i++] = array[s1++];
} else {
tmp[i++] = array[s2++];
}
}
//判断两个归并段 中 是否还有归并段有数据
while(s1 <= mid) {
tmp[i++] = array[s1++];
}
while(s2 <= high) {
tmp[i++] = array[s2++];
}
for (int j = 0; j < len; j++) {
array[low + j] = tmp[j];
}
}