归并排序
1、基本思想:
归并排序就是利用归并的思想实现的排序方法。而且充分利用了完全二叉树的深度是的特性,因此效率比较高。其基本原理如下:对于给定的一组记录,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序,最后再用递归方法将排好序的半子表合并成为越来越大的有序序列。
经过第一轮比较后得到最小的记录,然后将该记录的位置与第一个记录的位置交换;接着对不包括第一个记录以外的其他记录进行第二次比较,得到最小记录并与第二个位置记录交换;重复该过程,知道进行比较的记录只剩下一个为止。
2. 工作原理
相当于拆分两个有序的数组
-
1.申请一个临时数组,数组大小为原来数组的大小,该空间用来存放合并后的序列
-
2.设定两个指针,最初的位置分别都为数组的起始位置
-
3.比较两个数组每个元素的大小,将相对较小的元素放置在临时数组中,并移动下一个位置进行比较
-
4.重复步骤3直到某一指针达到序列尾
-
5.将另一序列剩下的所有元素直接复制到合并序列尾
2.1首先从左数组leftArr[0]跟有数组rightArr[0]进行比较,谁小就放在临时大数组。并向后移进行再次比较。
public class MergeSort {
public static void main(String[] args) {
int[] arr = new int[100];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 100);
}
long startTime = System.currentTimeMillis();
mergeSort(arr, 0, arr.length - 1);
System.out.println("排序结果:" + Arrays.toString(arr));
long endTime = System.currentTimeMillis();
System.out.println("花费" + ((endTime - startTime) / 1000) + "秒");
}
/**
* 合并数组
*
* @param arr 原始数组
* @param low 指向左数组第一个元素
* @param high 指向数组最后的元素
* @param mid 指向两数组分隔的元素
*/
public static void merge(int[] arr, int low, int high, int mid) {
//申请一个临时数组,数组大小为原来数组的大小,该空间用来存放合并后的序列
//这里为什么临时数组容量为 high - low + 1???
//因为将之划分为两个数组 leftArr[mid - low] rightArr[high - mid + 1]
//合并成一个大数组就是 high - low + 1
int[] temp = new int[high - low + 1];
//左边数组的起始位置
int i = low;
//右边数组的起始位置
int j = mid + 1;
//临时数组索引
int key = 0;
//把较小的数先移到新数组中
while (i <= mid && j <= high) {
//相当于左边的数组小于右边的
if (arr[i] < arr[j]) {
temp[key++] = arr[i++];
} else {
//右边的数组小
temp[key++] = arr[j++];
}
}
//把左边剩余的位置直接填充到临时数组中
while (i <= mid) {
temp[key++] = arr[i++];
}
//把右边的数组剩余的位置填充到临时数组中
while (j <= high) {
temp[key++] = arr[j++];
}
//将临时数组拷贝到原数组
for (int t = 0; t < temp.length; t++) {
//数组拷贝 arr原数组是从low这个位置开始的
//相当于 System.arraycopy(temp, 0, arr, 0 + low, temp.length); 从 low这位置开始将数据拷贝
arr[t+low] = temp[t];
}
}
/**
* 合并排序
*
* @param arr
* @param low
* @param high
*/
public static void mergeSort(int[] arr, int low, int high) {
int mid = (high + low) >> 1;
//只要一个元素,不需要排序
if (low == high) {
return;
}
if (low < high) {
//左边排序
mergeSort(arr, low, mid);
//右边排序
mergeSort(arr, mid + 1, high);
//左右归并
merge(arr, low, high, mid);
// System.out.println(Arrays.toString(arr));
}
}
}