归并排序
定义及解析
实际上是分治算法的思想,将大问题分成小问题,再将小问题结果合成大问题的结果。由此一来减小复杂问题求解的难度。
下面整形数组为例,首先将数组不断以中轴每每分成两组,直到不可分割位置,之后每小组排序,再将排序完后的结果合并
起来。例如 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) ) ;
}
}