为了账号安全,请及时绑定邮箱和手机立即绑定

在python中实现归并排序时出现错误

在python中实现归并排序时出现错误

大话西游666 2021-08-11 22:04:47
我正在尝试在 python 中实现合并排序,如下所示:def MergeSortTopdown(list_n):     #Base condition to stop recursion    if len(list_n) == 1:        return list_n    else:        mid = int(len(list_n)/2)        first_half = list_n[:mid]        second_half = list_n[mid:]        MergeSortTopdown(first_half)        MergeSortTopdown(second_half)        i = 0        j = 0         n = len(list_n)        for k in range(n):            if j >= len(first_half) and i < len(second_half):                list_n[k] = first_half[i]                i += 1             if i >= len(first_half) and j < len(second_half):                 list_n[k] = second_half[j]                j += 1            if i < len(first_half) and j < len(second_half):                if first_half[i] > second_half[j]:                    list_n[k] = second_half[j]                    j += 1                   elif second_half[j] > first_half[i]:                    list_n[k] = first_half[i]                    i += 1                elif second_half[i] == first_half[j]:                    list_n[k] = first_half[i]                    if i>j:                        i += 1                    else:                        j += 1    return list_n当我用已经排序的列表进行测试时,这似乎是合理的。但是,当我运行时,会出现此错误:MergeSortTopdown([3,4,6,7,1,8,56,112,67])Traceback (most recent call last):  File "<ipython-input-11-29db640f4fc6>", line 1, in <module>    MergeSortTopdown([3,4,6,7,1,8,56,112,67])  File "C:/Users/Emmanuel Hoang/MergeSortTopDown.py", line 13, in MergeSortTopdown    MergeSortTopdown(second_half)  File "C:/Users/Emmanuel Hoang/MergeSortTopDown.py", line 13, in MergeSortTopdown    MergeSortTopdown(second_half)  File "C:/Users/Emmanuel Hoang/MergeSortTopDown.py", line 19, in MergeSortTopdown    list_n[k] = first_half[i]IndexError: list index out of range你能告诉我我的代码有什么问题吗,有什么办法可以改进我的代码。先感谢您
查看完整描述

2 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

您试图引用列表末尾之后的元素。我print在您的代码中添加了一些简单的语句:


   for k in range(n):

        print("LOOP TOP", k, first_half, second_half, list_n)

        if j >= len(first_half) and i < len(second_half):

            print("TRACE", list_n, k, "\t", first_half, i)

            list_n[k] = first_half[i]

            i += 1

然后我将输入列表缩短为[8,56,112,3,67].


输出:


LOOP TOP 0 [8] [56] [8, 56]

LOOP TOP 1 [8] [56] [8, 56]

LOOP TOP 0 [3] [67] [3, 67]

LOOP TOP 1 [3] [67] [3, 67]

LOOP TOP 0 [112] [3, 67] [112, 3, 67]

LOOP TOP 1 [112] [3, 67] [3, 3, 67]

TRACE [3, 3, 67] 1   [112] 0

LOOP TOP 2 [112] [3, 67] [3, 67, 67]

TRACE [3, 67, 67] 2      [112] 1

接下来是您遇到的崩溃。first_half[1]当只有一个元素 0 时,您尝试获取。


分析


您有三个连续的if语句来检查列表边界:


        if j >= len(first_half) and i < len(second_half):

        if i >= len(first_half) and j < len(second_half): 

        if i < len(first_half) and j < len(second_half):

你必须i和j在第一检查切换:i是first_half下标。此更改修复了合并:


        if i < len(first_half) and j >= len(second_half):

建议


您的部分问题是您的合并逻辑过于复杂。在循环的主要部分,您有一个单一的值检查:将较低的列表头移动到合并的列表中。在两个索引都在范围内时执行此操作。


然后,当一个索引到达其列表的末尾时,退出循环并添加另一个列表的剩余元素。使用extend方法。所以 ...


while i < len(first_half) and j < len(second_half):

    if first_half[i] < second_half[j]:

        # move smaller element to list_n;

        # increment i or j as needed

    k += 1


# One of these will be an empty operation.

list_n.extend(first_half[i:])

list_n.extend(second_half[j:])


查看完整回答
反对 回复 2021-08-11
?
POPMUISE

TA贡献1765条经验 获得超5个赞

要解决IndexError:

您在合并排序的“合并步骤”中检查的第一种情况——如果您已经合并了列表中的所有元素second_half——具有两个列表的名称first_half并second_half切换。取而代之的是:


if j >= len(first_half) and i < len(second_half):

    list_n[k] = first_half[i]

    i += 1 

你应该有这个:


if j >= len(second_half) and i < len(first_half):

    list_n[k] = first_half[i]

    i += 1

这将正确检查上面指定的条件。


为什么会这样:

您收到 an 的原因IndexError是因为您在尝试调用first_half[i]之前没有正确确认这i是列表中的有效索引first_half。


查看完整回答
反对 回复 2021-08-11
  • 2 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号