归并排序
定义及解析
实际上是分治算法的思想,将大问题分成小问题,再将小问题结果合成大问题的结果。由此一来减小复杂问题求解的难度。
下面整形数组为例,首先将数组不断以中轴每每分成两组,直到不可分割位置,之后每小组排序,再将排序完后的结果合并
起来。例如 int arr[] = new int[]{1,6,4,9,43,10,6,5};这个数组第一次分割成 1,6,4,9和43,10,6,5两组,然后处理右边
分组在处理左边分组;第二次分组 1,6 和 4,9两组;第三次分组,1和6两组,已不可分组。如此循环下去直到不可分组为止。
升序排序,然后判断右分区元素和左分区元素大小,并把大的存入辅助数组中,然后相应指针加一,判断左右指针是否到达边界,
如果是退出循环比较, while(left <= mid && right <= e){
if(arr[left] <= arr[right])
temp[pointer++]=arr[left++];
else
temp[pointer++]=arr[right++];
}
就是退出此段代码之后,因为左右指针不可能同时到达边界,此时我们需要将未到边界的指针所在的分区,并且是该指针之后的元素
拷贝到辅助数组当中去,也就是该代码块
while(left <= mid)
temp[pointer++] = arr[left++];
//相反
while(right <= e){
temp[pointer++] = arr[right++];
}
随后将辅助数组元素还原到原始数组相应的位置,也就是每两个分组的长度中去。
pointer = 0;
for(int i=0;i <temp.length;i++){
arr[i+s] = temp[i];
}
代码示例
采用递归实现
import java.util.Arrays;
public class Main {
public void mergeSort(int arr[] ,int start,int end){
if(end <= start) return;
int mid = start + (end-start)/2;
mergeSort(arr, start, mid);
mergeSort(arr, mid+1, end);
merge(arr, start, end, mid);
}
private static void merge(int[] arr,int s,int e,int mid){
int temp[] = new int[e-s+1];
int left = s;
int right = mid+1;
int pointer = 0;
while(left <= mid && right <= e){
if(arr[left] <= arr[right])
temp[pointer++]=arr[left++];
else
temp[pointer++]=arr[right++];
}
System.out.println("pointer"+pointer);
while(left <= mid)
temp[pointer++] = arr[left++];
while(right <= e){
temp[pointer++] = arr[right++];
}
pointer = 0;
for(int i=0;i <temp.length;i++){
arr[i+s] = temp[i];
}
}
public static void main(String[] args) {
int arr[] = new int[]{1,6,4,9,43,10,6,5};
Main main = new Main();
main.mergeSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}