本篇博客主要是介绍归并排序
归并排序的核心是归并俩个已经有序的数组
首先我们先针对俩个有序的数组进行合并排序
/**
* arr1 第一个有序的数组
* size1 数组一的大小
* arr2 第二个有序的数组
* size2 数组二的大小
* arr3 保存数组一和数组二合并以后并排序的数组
*/
public static void sort(int arr1[], int size1, int arr2[], int size2, int arr3[]) {
int index1 = 0, index2 = 0, index3 = 0; // 分别记录三个数组的索引
while (index1 < size1 && index2 < size2) { // 如果俩个有序数组的索引都在合理范围
// 比较赋值
if (arr1[index1] < arr2[index2]) {
arr3[index3++] = arr1[index1++];
} else {
arr3[index3++] = arr2[index2++];
}
}
while (index1 < size1) { // 数组2已经遍历排序完成,数组1还有数据没有遍历排序
arr3[index3++] = arr1[index1++];
}
while (index2 < size2) {
arr3[index3++] = arr2[index2++];
}
}
下面我们介绍如何对对一个数组进行排序
根据上面的例子,可以知道首要要把一个数组拆分成俩个数组,然后对每一半的数组进行排序,形成有序数组。然后在通过归并排序实现数组有序。
那么问题来了如何将一个数组拆分成俩个数组并分别排序呢?
递归来了
不断的对数组进行折半拆分并进行归并排序。
拆分
/**
* 对数组进行拆分
* 注意该地方的拆分并不是真的将数组拆分了
* source 数据源
* arr 最后保存有序数据的数组
* start 拆分数组的起始位置
* end 拆分数组的结束位置
*/
public static void split(int source[], int arr[], int start, int end) {
if (start == end) { // 递归结束条件
return;
}
// 获取数组拆分的位置
int mid = (start + end) / 2;
// 通过递归分割前面数据
split(source, arr, start, mid);
// 通过递归分割后面数据
split(source, arr, mid + 1, end);
// 排序
sort(source, arr, start, mid + 1, end);
}
排序
/**
* 排序 (将leftPtr到rightBound的数据进行排序)
*
* @param source
* 数据源
* @param arr
* 最后保存有序数据的数组
* @param leftPtr
* 左起始位置
* @param rightPtr
* 右起止位置
* @param rightBound
* 右边界
*/
public static void sort(int source[], int arr[], int leftPtr, int rightPtr, int rightBound) {
int index = 0; // arr 下标索引
int mid = rightPtr - 1; // 分割位置 分为左右俩部分模拟俩个数组
int leftBound = leftPtr; // 计算左边界
int n = rightBound - leftBound + 1; // 数据个数
// 保证新数组中数据有序
while (leftPtr <= mid && rightPtr <= rightBound) {
if (source[leftPtr] < source[rightPtr]) {
arr[index++] = source[leftPtr++];
} else {
arr[index++] = source[rightPtr++];
}
}
while (leftPtr <= mid) { // 右边的已经遍历比较结束 直接通过左边数据赋值
arr[index++] = source[leftPtr++];
}
while (rightPtr <= rightBound) { // 左边的已经遍历比较结束 直接通过右边数据赋值
arr[index++] = source[rightPtr++];
}
// 更新数据源数据顺序 保证本次合并数据的在原始数组有序
for (int i = 0; i < n; i++) {
source[leftBound + i] = arr[i];
}
}