归并排序混淆的类型

Type Of Merge Sort Confusion

本文关键字:类型 归并排序      更新时间:2023-10-16

我被要求写两种类型的归并排序。一种是时间为(n lgn)的二元归并排序,另一种是时间为O(n lgn)的自然归并排序。我找遍了所有地方,想了解他们每个人的工作。我很难理解这些差异,我只需要一些解释或例子就好了。我写了一个归并排序但我得到的是自然归并排序还是二元归并排序?

bool compareElements(int i, int j)
{
    ++COMPARE_COUNT;
    //int *t = i;
     return i < j;
}
void merge(int values[], int left[], int right[], int middle, int total)  
{
int left_size = middle, right_size = total - middle;
int i = 0, j = 0;
// Loop through values array
for (int k = 0; k < total; k++)
{
    // If elements left on left and either no elements on right 
    // or left is larger than right, then use next left value
    if (i < left_size && (j >= right_size || left[i] <= right[j]))
    {
        values[k] = left[i];
        i++;
    }
    // else use next right value
    else
    {
        values[k] = right[j];
        j++;
    }
  }
}
void mergeSort(int values[], int n,bool result)  
{
if(result == false)
{
    if (n < 2)
    {
        return;
    }
    int middle = n / 2;
    int *left = new int [middle];
    int *right = new int [n - middle];
    for (int i = 0; i < n; i++)
    {
        //COMPARE_COUNT++;
        if(compareElements(i,middle))        //(i < middle)
        {
            SWAP_COUNT++;
            left[i] = values[i];
        }
        else if(!compareElements(i,middle))
        {
            SWAP_COUNT++;
            right[i - middle] = values[i];
        }
    }
    mergeSort(left, middle,result);
    mergeSort(right, n - middle,result);
    merge(values, left, right, middle, n);
}
}

二进制归并排序有一个非常简单的递归定义:将输入数组分成两半,使用二进制归并排序对这两半进行排序,将这两半合并成一个有序的序列。这是你实现的。

另一个版本是自下而上归并排序。这首先将一个序列分割成长度为1的子序列,然后开始合并它们。

一个自然归并排序有一个不同的第一步步骤。它不会将输入序列分成两部分,而是分成运行。run是递增或递减的元素序列。例如下面的数组:

0 1 4 2 3 9 8 7 5 2 1 3 4 2 4 3 4

可以分成如下几行:

0 1 4 | 2 3 9 | 8 | 7 | 5 | 2 | 1 3 4 | 2 4 | 3 4

每次运行都是升序的。然后你开始合并运行,就像你在合并排序中一样,除了你从下往上合并

这被称为自然归并排序的原因是,如果你的输入已经(部分)预先排序,算法将开始接近O(n)的最佳情况性能。