//归并排序,自顶而下
//对于长度为N的任意数组,需要0.5NlgN至NlgN次比较
//对于长度为N的任意数组,最多需要访问数组6NlgN次
void merge(vector<int>& a,int low,int mid,int high) {
vector<int>aux(a.begin(), a.end());
int i = low, j = mid + 1;
for (int k = low; k <= high; ++k) {
if (i > mid) a[k] = aux[j++];
else if (j > high) a[k] = aux[i++];
else if (aux[i] <= aux[j]) a[k] = aux[i++];
else a[k] = aux[j++];
}
}
void merge_sort(vector<int>& a, int low, int high) {
if (low >= high) return;
int mid = low + (high - low) / 2;
merge_sort(a, low, mid);
merge_sort(a, mid + 1, high);
merge(a, low, mid, high);
}
//优化方法:
//1、对小规模数组使用插入排序
//2、测试数组是否已经有序,如果a[mid]<=a[mid+1],则跳过merge()方法
//3、将数据输入数组排序到辅助数组,将数据从辅助数组排序到输入数组
//自底而上,归并排序
//两两归并->四四归并->八八归并...
//对于长度为N的任意数组,需要0.5NlgN至NlgN次比较,最多访问数组NlgN次
void merge(vector<int>& a, int low, int mid, int high) {
vector<int>aux(a.begin(), a.end());
int i = low, j = mid + 1;
for (int k = low; k <= high; ++k) {
if (i > mid) a[k] = aux[j++];
else if (j > high) a[k] = aux[i++];
else if (aux[i] <= aux[j]) a[k] = aux[i++];
else a[k] = aux[j++];
}
}
void mergeBU_sort(vector<int>& a, int low, int high) {
int n = a.size();
for (int sz = 1; sz <= n; sz *= 2) {
for (int lo = 0; lo <= n - sz * 2; lo += sz * 2) {
merge(a, lo, lo + sz - 1, min(lo + sz * 2 - 1, n));
}
}
}
//自底而上的归并排序比较适合链表组织数据
//只需重新组织链表链接就能将链表原地排序(无需创建新的链表节点)
//当数组长度为2的幂时,自底而上和自顶而下的归并排序的
//比较次数和访问数组次数正好相同,只是顺序不同
//归并排序是一种渐进最优的基于比较排序的算法
【算法第四版读书笔记】归并排序
最新推荐文章于 2024-09-10 09:42:10 发布