分治法Q2——归并排序
package 分治法;
public class 归并排序 {
/**
* 1.recursion terminator
* 2.process(prepare data,split your big problem do the current logic)
* 3.dirll down(subproblems),merge(subresults)
* 4.reverse the current level states if needed
*/
public void mergeSort(int[] nums,int begin,int end) {
//1.recursion terminator
if(begin<end) {
//2.process
//prepare data
int mid=begin+((end-begin)>>1);//中间元素 除以二是右移一位不是>>2 老是写错
//split your big problem
//System.out.println(nums[mid]);
//3.drill down
mergeSort(nums,begin,mid);
mergeSort(nums,mid+1,end);
//merge
merge(nums,begin,mid,end);
}
}
int []helper;
public void merge(int[] nums, int begin,int mid, int end) {
//应该在原数组nums进行修改 因为划分是一半一半地进行的
//下次扔进来的nums数组时是merge过的已经部分有序
//当左右区间划分到只剩下这个元素本身时 merge开始调用
//将a中已经分区部分元素拷贝到helper中
helper=new int[nums.length];
System.arraycopy(nums,begin,helper,begin,end-begin+1);
int left=begin;//左侧队伍头指针 指向待比较元素
int right=mid+1;//右侧队伍头指针 指向待比较元素
int current=begin;//新生成数组指针 指向待填入数据的位置
while(left<=mid&&right<=end) {
if(helper[left]<=helper[right]) {
nums[current++]=helper[left++];
}else {
nums[current++]=helper[right++];
}
}
//当左边还有元素剩余
while(left<=mid) {
nums[current++]=helper[left++];
}
for (int i : nums) {
System.out.print(i+" ");
}
System.out.println();
}
public static void main(String[] args) {
归并排序 a=new 归并排序();
//int []nums=new int[] {10,5,1,7,2,3,6,4,8,9};
int []nums=new int[] {1,2,3,4,5,6,7,8,9,10};
a.mergeSort(nums, 0, nums.length-1);
}
}
最后一次归并过程merge(nums,0,9)