voidMerge(int a[], int s, int m, int e, int tmp[]){ // O(n) // 对区间 [s, m] 和 [m + 1, e]两个区间的数组进行合并,存储到tmp; // 然后保证tmp有序,然后再将tmp的内容拷贝会 a[s, e] int pb = 0; // tmp 数组的下标 int p1 = s; // p1, p2 为两个区间的开始索引指针 int p2 = m + 1; while(p1 <= m && p2 <= e){ // 在两个子数组中,比较两个指针指向的两个数, if(a[p1] < a[p2]){ // 较小的数存入tmp,同时索引递增 tmp[pb++] = a[p1++]; //直到有其中一个子数组所有值已经被复制到tmp后停止 } else{ tmp[pb++] = a[p2++] } } // 这里直接按顺序将未写入到tmp的数写入。因为底层归并时,已经排序好了。 while( p1 <= m){ tmp[pb++] = a[p1++]; } while( p2 <= e){ tmp[pb++] = a[p2++]; } // 复制值回到原始数组 for(int i = 0; i < pb; i++){ a[s + i] = tmp[i]; } }
voidMergeSort(int a[], int s, int e, int tmp[]){ /* a: 待排序的数组 s:开始排序的下标 e: 结束排序的下标 tmp: 临时存放排序的数组 */ // 当开始下标和结束下标大小一致时,结束归并 if (s < e){ int m = s + (e - s) / 2; MergeSort(a, s, m, tmp); MergeSort(a, m, e, tmp); Merge(a, s, m, e, tmp); } }