[英]Errors arises when implement merge sort in python
I'm trying to implement merge sort in python as following: 我正在尝试在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
it seems reasonable when I tested with already sorted list. 当我测试已经排序的列表时,这似乎是合理的。 However, when I run, this error raises:
但是,当我运行时,此错误引发:
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
Can you tell me what's wrong with my code, is there any way that I can improve my code. 您能告诉我我的代码有什么问题吗,有什么方法可以改善我的代码。 Thank you in advance
先感谢您
You've tried to reference an element past the end of the list. 您试图引用列表末尾的元素。 I added some straightforward
print
statements to your code: 我在代码中添加了一些简单的
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
Then I shortened the input list to [8,56,112,3,67]
. 然后,我将输入列表缩短为
[8,56,112,3,67]
。
Output: 输出:
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
This is followed by the crash you got. 其次是您崩溃。 You try to fetch
first_half[1]
when there's only an element 0. 当只有元素0时,您尝试获取
first_half[1]
。
ANALYSIS 分析
You have three successive if
statements to check list bounds: 您具有三个连续的
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):
You have i
and j
switched in the first check: i
is the first_half
subscript. 您在第一个检查中切换了
i
和j
: i
是first_half
下标。 This change fixes the merge: 此更改修复了合并:
if i < len(first_half) and j >= len(second_half):
Suggestions 建议
Part of your problem is that your merge logic is too complex. 问题的部分原因是合并逻辑太复杂。 You have a single value check during the main part of the loop: move the lower of the list heads to the merged list.
在循环的主要部分中,您需要进行一次值检查:将列表标题的下半部分移到合并列表中。 Do this while both indices are in range.
当两个索引都在范围内时执行此操作。
Then, when one index hits the end of its list, drop out of the loop and add the remaining elements of the other list. 然后,当一个索引到达其列表的末尾时,退出循环并添加另一列表的其余元素。 Use the
extend
method. 使用
extend
方法。 So ... 所以...
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:])
IndexError
: IndexError
: The first case that you check for in your 'merge step' of the merge sort -- if you have already merged all elements from the list second_half
-- has the names of your two lists first_half
and second_half
switched around. 如果你已经合并列表中的所有元素-你在合并排序的你“的合并操作”检查第一种情况
second_half
-有你的两个列表的名称first_half
和second_half
切换左右。 Instead of this: 代替这个:
if j >= len(first_half) and i < len(second_half):
list_n[k] = first_half[i]
i += 1
you should have this: 你应该有这个:
if j >= len(second_half) and i < len(first_half):
list_n[k] = first_half[i]
i += 1
This will correctly check for the condition specified above. 这将正确检查上面指定的条件。
The reason why you received an IndexError
is because you were trying to call first_half[i]
and were not correctly confirming that i
was a valid index in the list first_half
before doing so. 之所以收到
IndexError
是因为您试图调用first_half[i]
并且在执行此操作之前未正确确认i
是first_half
列表中的有效索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.