C 有没有办法使这个合并排序算法更有效?
因此,我有这个合并排序算法,我需要减少比较的数量。除了我已经拥有的数据结构之外,我不允许使用任何额外的数据结构。我完全不知道如何才能使这更有效。有人能帮忙吗C 有没有办法使这个合并排序算法更有效?,c,algorithm,sorting,mergesort,C,Algorithm,Sorting,Mergesort,因此,我有这个合并排序算法,我需要减少比较的数量。除了我已经拥有的数据结构之外,我不允许使用任何额外的数据结构。我完全不知道如何才能使这更有效。有人能帮忙吗 int compares = 0; // Merge two sorted subarrays arr[low .. mid] and arr[mid + 1 .. high] void Merge(int arr[], int aux[], int low, int mid, int high) { int k = low, i
int compares = 0;
// Merge two sorted subarrays arr[low .. mid] and arr[mid + 1 .. high]
void Merge(int arr[], int aux[], int low, int mid, int high)
{
int k = low, i = low, j = mid + 1;
// While there are elements in the left and right runs
while (i <= mid && j <= high)
{
if (arr[i] <= arr[j])
aux[k++] = arr[i++];
compares++;
else
aux[k++] = arr[j++];
}
// Copy remaining elements
while (i <= mid)
aux[k++] = arr[i++];
// No need to copy the second half
// copy back to the original array to reflect sorted order
for (int i = low; i <= high; i++)
arr[i] = aux[i];
}
// Sort array arr [low..high] using auxiliary array aux
void MergeSort(int arr[], int aux[], int low, int high)
{
// Base case
if (high == low) // if run size == 1
return;
// find mid point
int mid = (low + ((high - low) >> 1));
// recursively split runs into two halves until run size == 1,
// then merge them and return back up the call chain
MergeSort(arr, aux, low, mid); // split / merge left half
MergeSort(arr, aux, mid + 1, high); // split / merge right half
Merge(arr, aux, low, mid, high); // merge the two half runs
}
int=0;
//合并两个已排序的子数组arr[low..mid]和arr[mid+1..high]
无效合并(整数arr[]、整数aux[]、整数low、整数mid、整数high)
{
int k=低,i=低,j=中+1;
//而左、右梯段中都有元素
而(i您的代码中存在一些问题:
Merge
函数不正确:右数组中的剩余元素没有复制到aux
数组,这很好(无需复制后半部分),但将元素复制回arr
的最后一个循环应该在i
处停止,而不是运行到i。如果排序实际上是合并排序,则它将是O(n lg n)比较。应该减少什么“比较”?请注意merge()
函数不计算它执行的所有项目比较。它只在arr[i]时更新变量compares
,这样可以提高算法的效率(但不会减少项目比较的数量),通过避免从辅助数组复制回数据的步骤(可能在结尾处除外)。相反,从递归的底部向上提升时,在哪个数组被视为主数组和哪个辅助数组之间来回翻转。对不起,我应该澄清这一点,但我应该计算的唯一比较是数组之间的比较访问。
int compares = 0;
// Merge two sorted subarrays arr[low .. mid] and arr[mid + 1 .. high]
void Merge(int arr[], int aux[], int low, int mid, int high) {
int k = low, i = low, j = mid + 1;
// While there are elements in the left and right runs
while (i <= mid && j <= high) {
compares++;
if (arr[i] <= arr[j])
aux[k++] = arr[i++];
else
aux[k++] = arr[j++];
}
// Copy remaining elements
while (i <= mid)
aux[k++] = arr[i++];
// No need to copy the second half
// copy back to the original array to reflect sorted order
for (int i = low; i < k; i++)
arr[i] = aux[i];
}
// Sort array arr [low..high] using auxiliary array aux
void MergeSort(int arr[], int aux[], int low, int high) {
// Base case
if (high == low) // if run size == 1
return;
// find mid point
int mid = low + ((high - low) >> 1);
// recursively split runs into two halves until run size == 1,
// then merge them and return back up the call chain
MergeSort(arr, aux, low, mid); // split / merge left half
MergeSort(arr, aux, mid + 1, high); // split / merge right half
Merge(arr, aux, low, mid, high); // merge the two half runs
}
int compares = 0;
// Merge two sorted subarrays arr[low .. mid] and arr[mid + 1 .. high]
void Merge(int arr[], int aux[], int low, int mid, int high) {
int k = low, i = low, j = mid + 1;
// Extra comparison to improve special case of sorted arrays
if (high - low > 7) {
compares++;
if (arr[mid] <= arr[j])
return;
}
// While there are elements in the left and right runs
while (i <= mid && j <= high) {
compares++;
if (arr[i] <= arr[j])
aux[k++] = arr[i++];
else
aux[k++] = arr[j++];
}
// Copy remaining elements
while (i <= mid)
aux[k++] = arr[i++];
// No need to copy the second half
// copy back to the original array to reflect sorted order
for (int i = low; i < k; i++)
arr[i] = aux[i];
}