public static void main(String[] args) {
int[] a = {11,8,3,9,7,1,2,5};
int n = a.length;
mergeSort(a,0,n-1,n);
System.out.println(Arrays.toString(a));
}
/**
* 归并排序
* 1.递归公式:
* mergeSort(p...r) = merge(mergeSort(p...q),mergeSort(q+1...r))
* 2.终止条件:
* p>=r
* @param a
* @param low
* @param hight
* @param n
*/
public static void mergeSort(int[] a,int low,int hight,int n){
/**
* 终止条件为什么是 low >= hight
* 3,2,1 low=0,hight=2,mid=1
* 3,2 low=0,hight=1,mid=0
* 3 low=0,hight=0,应退出
*/
if(low >= hight){
return;
}
/**
* 为什么不写成 (low+hight)/2
* 1.low+hight 存在溢出风险
* 2. >>1相比 /2,计算机对位移操作执行效率更好
*
* >> 、<< 右移、左移运算符优先级低于 + 、-
*/
int mid = low + ((hight - low) >> 1);
mergeSort(a,low,mid,n);
mergeSort(a,mid + 1,hight,n);
merge(a,low,mid,mid+1,hight,n);
}
/**
* 合并
* @param a
* @param lowStart
* @param lowEnd
* @param hightStart
* @param hightEnd
* @param n
*/
public static void merge(int[] a,int lowStart,int lowEnd,int hightStart,int hightEnd,int n){
int[] temp = new int[n];
//低位遍历指针
int i = lowStart;
//高位遍历指针
int j = hightStart;
//temp插入位置
int k = 0;
while(i <= lowEnd && j <= hightEnd){
/**
* 为何不写为 a[i] < a[j]
* 为了保证算法稳定性
* 两者相等时,应将左侧(即a[i])元素仍放置在左侧
*/
if(a[i] <= a[j]){
temp[k++] = a[i++];
}else{
temp[k++] = a[j++];
}
}
if(j <= hightEnd){
while(j <= hightEnd){
temp[k++] = a[j++];
}
}
if(i <= lowEnd){
while(i <= lowEnd){
temp[k++] = a[i++];
}
}
for(int l = lowStart; l <= hightEnd; l++){
a[l] = temp[l-lowStart];
}
}
归并排序
最新推荐文章于 2023-12-11 10:45:47 发布