void merge(int[] a, int lo, int mid, int hi, int[] aux) {
for (int k = lo; k <= mid; k++) {
aux[k] = a[k];
}
for (int k = mid + 1;k <= hi; k++) {
aux[k] = a[hi - k + mid + 1];
}
int i = lo, j = hi; //从两端往中间
for (int k = lo; k <= hi; k++)
if (aux[i] <= aux[j]) a[k] = aux[i++];
else a[k] = aux[j--];
}
if (nRemaining < MIN_MERGE) {
int initRunLen = countRunAndMakeAscending(a, lo, hi);
binarySort(a, lo, hi, lo + initRunLen);
return;
}
int minRun = minRunLength(nRemaining);
do {
//找出下一个分区的起始位置,同时也对反向序列做了翻转处理
int runLen = countRunAndMakeAscending(a, lo, hi);
//保证run stack中的run的都大于minRun ,如果当前分区太小,就从后面取出元素补足
if (runLen < minRun) {
int force = nRemaining <= minRun ? nRemaining : minRun;
binarySort(a, lo, lo + force, lo + runLen);
runLen = force;
}
//把run放入 run stack中
ts.pushRun(lo, runLen);
//判断是否应该合并,i是从栈顶开始的,知道不能合并为止
//1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]
//2. runLen[i - 2] > runLen[i - 1]
ts.mergeCollapse();
lo += runLen;
nRemaining -= runLen;
} while (nRemaining != 0);
// Merge all remaining runs to complete sort
assert lo == hi;
//合并剩下的run
ts.mergeForceCollapse();
assert ts.stackSize == 1;
/**
* 如果后2个run的长度加起来比前面一个长,则使用中间位置的run和前后长度更短的run一个合并
* 如果后2个run的长度加起来比前面一个短,则把后面2个run合并
*/
private void mergeCollapse() {
while (stackSize > 1) {
int n = stackSize - 2;
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
if (runLen[n - 1] < runLen[n + 1])
n--;
mergeAt(n);
} else if (runLen[n] <= runLen[n + 1]) {
mergeAt(n);
} else {
break; // Invariant is established
}
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有