我正在尝试理解下面用于合并排序的python代码。
函数mergeSort
没有返回任何值,也没有将排序列表存储到lefthalf
变量。那么在调用函数之后,变量lefthalf
的值如何变化{例如变为[26,54]}。
def mergeSort(alist):
print("Splitting ",alist)
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
print("Before left call------>",lefthalf)
mergeSort(lefthalf)
print("after left call------>",lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
alist[k]=lefthalf[i]
i=i+1
else:
alist[k]=righthalf[j]
j=j+1
k=k+1
while i < len(lefthalf):
alist[k]=lefthalf[i]
i=i+1
k=k+1
while j < len(righthalf):
alist[k]=righthalf[j]
j=j+1
k=k+1
print("Merging ",alist)
alist = [54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)
输出
Splitting [54, 26, 93, 17, 77, 31, 44, 55, 20]
Before left call------> [54, 26, 93, 17]
Splitting [54, 26, 93, 17]
Before left call------> [54, 26]
Splitting [54, 26]
Before left call------> [54]
Splitting [54]
Merging [54]
after left call------> [54]
Splitting [26]
Merging [26]
Merging [26, 54]
after left call------> [26, 54]
Splitting [93, 17]
Before left call------> [93]
Splitting [93]
Merging [93]
after left call------> [93]
Splitting [17]
Merging [17]
Merging [17, 93]
... ......依此类推,直至排序清单。
提前谢谢。
答案 0 :(得分:0)
数组内容会在函数末尾写回alist
,而alist
lefthalf
位于上一级。
当我从C切换到Python时,我发现这真的很混乱,但在Python中,一切都是对象的引用,所以所有函数调用都是有效的pass-by-reference。
答案 1 :(得分:0)
首先,在lefthalf = alist[:mid]
和righthalf = alist[mid:]
。它创建了两个新列表:lefthalf和rightlhalf,它们是alist中左半部分整数和右半部分整数的副本。更新这些列表时,alist不会更改。您可以使用以下代码进行测试:
>>> x = [1, 2, 3, 4]
>>> a = x[:2]
>>> a
[1, 2]
>>> b = x[2:]
>>> b
[3, 4]
>>> a[1] = 10
>>> a
[1, 10]
>>> b
[3, 4]
>>> x
[1, 2, 3, 4]
其次,在合并过程中,alist值就地突变。例如。当alist为[54,26]时,lefthalf为[54],righthalf为[26],merge将更新alist为[26,54]。这就是为什么在调用mergeSort(lefthalf)
时将lefthalf更改为[26,54]。
最后,当它调用megeSort(lefthalf)
和mergeSort(righthalf)
时,由于通过引用传递,它实际上更新了lefthalf和righthalft。这可以使用代码进行测试:
>>> l = [1, 2, 3]
>>> def update(x):
... x[0] = 100
...
>>> update(l)
>>> l
[100, 2, 3]
总而言之,整个过程是针对给定的alist,它创建了两个新列表:lefthalf和righthalf。在对lefthalf和righthalf进行排序之后,通过合并lefthalf和righthalf来更新alist。递归地执行此过程将对alist进行排序。
让我知道现在是否清楚。