为什么归并排序的 Merge() 函数有一个条件第二个循环?

发布于 2024-08-29 22:07:26 字数 975 浏览 6 评论 0原文

merge1(int low, int high, int S[], U[]) 
{ 
    int k = (high - low + 1)/2
    for q (from low to high) U[q] = S[q]
    int j = low 
    int p = low 
    int i = low + k 

    while (j <= low + k - 1) and (i <= high) do 
    { 
        if ( U[j] <= U[i] ) 
        {
            S[p] := U[j] 
            j := j+1
        } 
        else 
        { 
            S[p] := U[i] 
            i := i+1 
        } 
        p := p+1 
    } 

    if (j <= low + k - 1) 
    { 
        for q from p to high do 
        { 
            S[q] := U[j] 
            j := j+1 
        } 
    }
}


merge_sort1(int low, int high, int S[], U[]) 
{ 
    if low < high 
    { 
        int k := (high - low + 1)/2 
        merge_sort1(low, low+k-1, S, U) 
        merge_sort1(low+k, high, S, U) 
        merge1(low, high, S, U) 
    } 
}

所以,基本上,这是我的课堂笔记。我发现它总体上很混乱,但我理解其中最重要的部分。我不明白的是“if (j <= low + k - 1)”部分的需要。看起来它检查左侧部分是否有任何“剩余”元素。合并排序时这可能吗?

merge1(int low, int high, int S[], U[]) 
{ 
    int k = (high - low + 1)/2
    for q (from low to high) U[q] = S[q]
    int j = low 
    int p = low 
    int i = low + k 

    while (j <= low + k - 1) and (i <= high) do 
    { 
        if ( U[j] <= U[i] ) 
        {
            S[p] := U[j] 
            j := j+1
        } 
        else 
        { 
            S[p] := U[i] 
            i := i+1 
        } 
        p := p+1 
    } 

    if (j <= low + k - 1) 
    { 
        for q from p to high do 
        { 
            S[q] := U[j] 
            j := j+1 
        } 
    }
}


merge_sort1(int low, int high, int S[], U[]) 
{ 
    if low < high 
    { 
        int k := (high - low + 1)/2 
        merge_sort1(low, low+k-1, S, U) 
        merge_sort1(low+k, high, S, U) 
        merge1(low, high, S, U) 
    } 
}

So, basically, this is on my lecture notes. I find it quite confusing in general but I understand the biggest part of it. What I don't understand is the need of the "if (j <= low + k - 1)" part. It looks like it checks if there are any elements "left" in the left part. Is that even possible when mergesorting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

记忆里有你的影子 2024-09-05 22:07:26

合并两个排序列表(我们称其为 leftright)时,您会不断取出一项并将其添加到 result 列表中,直到您leftright 列表中的项目已用完。这是由第一个 while 循环完成的。现在您需要将左侧或右侧列表中剩余的元素添加到结果列表中。有两个选项:

  • 左边的列表没有元素,右边的列表还有一些。按照此处编写代码的方式,我们不需要执行任何操作,因为 S 数组的末尾已经包含 right 列表中的最后一个元素。 p>

  • 右边的列表已经没有元素了,左边的列表还有一些。然后我们将剩余的元素复制到S的末尾。这就是 merge1 末尾的 if 的作用。


关于您的问题此代码是否“不好”:代码是正确的,但我会进行一些更改以使其更具可读性:

  • 描述性变量名称。
  • 将分隔 leftright 列表的中点传递给 merge1,而不是重新计算。

When merging two sorted lists (let's call them left and right), you keep taking one item and adding it to the result list, until you run out of items in either the left or right list. This is done by the first while loop. Now you need to add the elements remaining in the left or right list to the result list. There are two options:

  • The left list is out of elements, and the right list still has some. The way the code is written here, we don't need to do anything, since the end of the S array already contains the last elements in the right list.

  • The right list is out of elements, and the left list still has some. Then we copy the remaining elements to the end of S. This is what the if at the end of merge1 does.


Regarding your question if this code is "bad": The code is correct, but I would make some changes to make it more readable:

  • Descriptive variable names.
  • Passing the midpoint which separates the left and right lists to merge1 instead of having it recalculated.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文