一、归并排序
/** * 归并排序: * 归并排序是建立在归并操作上的一种有效、稳定的排序算法。该算法采用分治的思想。 * 1.将n个元素分成各含n/2个元素的子序列 * 2.借助递归,两个子序列重复第一步的操作,直到不可再分 * 3.此时每层递归都有两个子序列,将其合并作为一个有序的子序列返回上一层,直到合并完成,得到有序的序列 * 关键在于两个子序列如何合并?假设两个子序列各自都是有序的,那么合并步骤就是: * 1.创建一个用于存放合并结果的数组,数组长度是两个子序列合并完成后的长度 * 2.设定两个指针,最初所指的位置分别为两个已经排序好的子序列的起始位置 * 3.比较两个指针所指的元素,把较小的放到结果数组中,然后指针移到下一位置 * 4.重复步骤3直到有一个指针移到序列尾 * 5.将另一序列剩下的元素合并到结果数组的序列尾部 */
public class _7_MergeSort {
public static void main(String[] args) {
Integer[] arr = {3, 5, 1, 7, 2, 3, 4, 8};
mergeSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
/**
* 归并排序
*/
public static void mergeSort(Integer[] arr, int low, int high) {
int middle = (high - low) / 2 + low;
if (low < high) {
//处理左边数组
mergeSort(arr, low, middle);
//处理右边数组
mergeSort(arr, middle + 1, high);
//合并
merge(arr, low, middle, high);
}
}
/**
* 合并
*/
public static void merge(Integer[] arr, int low, int middle, int high) {
//用于存储归并后的结果数组
int[] temp = new int[high - low + 1];
//记录第一个数组中需要遍历的指针
int i = low;
//记录第二个数组中需要遍历的指针
int j = middle + 1;
//记录结果数组的指针
int idx = 0;
//遍历两个数组
while (i <= middle && j <= high) {
//第一个数组的数更小
if (arr[i] <= arr[j]) {
temp[idx] = arr[i];
i++;
} else {
temp[idx] = arr[j];
j++;
}
idx++;
}
//处理剩余的数
while (i <= middle) {
temp[idx] = arr[i];
i++;
idx++;
}
while (j <= high) {
temp[idx] = arr[j];
j++;
idx++;
}
//把临时数组的值放回原数组
for (int k = 0; k < temp.length; k++) {
arr[k + low] = temp[k];
}
}
}
主要思想
1.分治,利用递归进行分半,直到不可再分
2.每层递归都会有两个子序列,创建一个两个子序列大小的临时数组存储数据
3.因为子序列是有序的,用双指针进行操作,依次进入临时数组