归并排序图解
归并排序是利用归并思想实现的排序,采用分治策略,将问题分成各个部分,然后将各个部分的到的答案合并到一起,继而治之。
思路及流程如下图:
如上图所示,将分后的元素进行排序组合,可以创建一个临时数组,假设采取从小到大的方式排序,比较指针i指向的元素的值和指针j指向的值,若j指针指向的元素的值较小,则将其加入temp中,接着j和t指针向后移动,代码如下:
//治,合并相邻两个子序列,从小到大
public static void merge(int[] arr, int left, int mid, int right, int[] temp){
//i指针指向左边有序序列的初始索引
int i = left;
//j指针指向右边有序序列的初始索引
//因为arr的长度可能是奇数,所以mid + 1
int j = mid + 1;
//指向temp当前索引
int t = 0;
//使temp中的元素有序
while (i <= mid && j <= right){
//如果i指向元素的值小于j指向的元素的值
//temp[t] = arr[i],t和i再分别后移
if (arr[i] <= arr[j]){
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
//如果满足条件表示还有元素未加入temp中
while (i <= mid){
temp[t++] = arr[i++];
}
while (j <= right){
temp[t++] = arr[j++];
}
//重置t,将temp中的元素拷贝到arr中
t = 0;
int tempLeft = left;
while (tempLeft <= right){
arr[tempLeft++] = temp[t++];
}
}
}
分的步骤如图:
因为需要经过多次分治,所以可以使用递归解决。
完整代码
public class MergeSort {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = new int[arr.length];
System.out.println("排列前的结果为:" + Arrays.toString(arr));
mergeSort(arr, 0, arr.length - 1, temp);
System.out.println("排列后的结果为:" + Arrays.toString(arr));
}
public static void mergeSort(int[] arr, int left, int right, int[] temp){
//结束条件
if (left < right) {
int mid = (left + right) / 2;
//处理左边
mergeSort(arr, left, mid, temp);
//处理右边
mergeSort(arr, mid + 1, right, temp);
//归并
merge(arr, left, mid, right, temp);
}
}
/**
*
* @param arr 数组
* @param left 初始索引
* @param mid 中间索引
* @param right 最后索引
* @param temp 临时数组
*/
//治,合并相邻两个子序列,从小到大
public static void merge(int[] arr, int left, int mid, int right, int[] temp){
//i指针指向左边有序序列的初始索引
int i = left;
//j指针指向右边有序序列的初始索引
//因为arr的长度可能是奇数,所以mid + 1
int j = mid + 1;
//指向temp当前索引
int t = 0;
//使temp中的元素有序
while (i <= mid && j <= right){
//如果i指向元素的值小于j指向的元素的值
//temp[t] = arr[i],t和i再分别后移
if (arr[i] <= arr[j]){
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
//如果满足条件表示还有元素未加入temp中
while (i <= mid){
temp[t++] = arr[i++];
}
while (j <= right){
temp[t++] = arr[j++];
}
//重置t,将temp中的元素拷贝到arr中
t = 0;
int tempLeft = left;
while (tempLeft <= right){
arr[tempLeft++] = temp[t++];
}
}
}
结果
排列前的结果为:[8, 4, 5, 7, 1, 3, 6, 2]
排列后的结果为:[1, 2, 3, 4, 5, 6, 7, 8]
还在学习中,有问题辛苦指出。