Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有没有办法使这个合并排序算法更有效?_C_Algorithm_Sorting_Mergesort - Fatal编程技术网

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];
    }