2 回答

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:])

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。
添加回答
举报