我正在尝试在python中实现mergeSort,但出现类型错误。
我尝试调试代码,但没有成功。
def merge(L, R):
(C, m, n) = ([], len(L), len(R))
(i,j) = (0,0)
while i+j < m+n:
if i == m: # Case 1 -> List A is empty
C.append(R[j])
j += 1
elif j == n: # Case 2 -> List B is empty
C.append(L[i])
i += 1
elif L[i] <= R[j]: # Case 3 -> Head of A is smaller
C.append(L[i])
i += 1
elif L[i] > R[j]:
C.append(R[j])
j += 1
print(C)
def mergeSort(A, left, right):
if right - left <= 1: # Base Case
return(A[left:right])
if right - left > 1: # Recurive call
mid = (left+right)//2
L = mergeSort(A, left, mid)
R = mergeSort(A, mid, right)
return(merge(L, R))
如果有人知道我在做什么错,请引导我以正确的方式。
答案 0 :(得分:3)
merge
必须返回C
,而不是打印出来。
def merge(L, R):
(C, m, n) = ([], len(L), len(R))
(i,j) = (0,0)
while i+j < m+n:
if i == m: # Case 1 -> List A is empty
C.append(R[j])
j += 1
elif j == n: # Case 2 -> List B is empty
C.append(L[i])
i += 1
elif L[i] <= R[j]: # Case 3 -> Head of A is smaller
C.append(L[i])
i += 1
elif L[i] > R[j]:
C.append(R[j])
j += 1
return C
答案 1 :(得分:0)
有没有更有效的方法来实现这一目标
使用一对相互递归的函数(msa2a,msa2b)自上而下进行合并排序,以更改合并的方向并避免复制数据:
def sort(a):
if(len(a) < 2): # if nothing to do, return
return
b = [0] * len(a) # allocate b
msa2a(a, b, 0, len(a)) # merge sort a to a
def msa2a(a, b, low, end): # merge sort a to a
if((end - low) < 2): # if < 2 elements
return # return
mid = (low+end)//2 # set mid point
msa2b(a, b, low, mid) # merge sort left half to b
msa2b(a, b, mid, end) # merge sort right half to b
mrg(b, a, low, mid, end) # merge halves from b to a
def msa2b(a, b, low, end): # merge sort a to b
if((end - low) < 2): # if < 2 elements
b[low] = a[low] # copy 1 element from a to b
return # return
mid = (low+end)//2 # set mid point
msa2a(a, b, low, mid) # merge sort left half to a
msa2a(a, b, mid, end) # merge sort right half to a
mrg(a, b, low, mid, end) # merge halves from a to b
def mrg(a, b, ll, rr, ee): # merge a pair of runs from a to b
o = ll # o = b[] index
l = ll # l = a[] left index
r = rr # r = a[] right index
while True:
if(a[l] <= a[r]): # if a[l] <= a[r]
b[o] = a[l] # copy a[l]
o += 1
l += 1
if(l < rr): # if not end of left run
continue # continue (back to while)
b[o:ee] = a[r:ee] # else copy rest of right run
return # and return
else: # else a[l] > a[r]
b[o] = a[r] # copy a[r]
o += 1
r += 1
if(r < ee): # if not end of right run
continue # continue (back to while)
b[o:ee] = a[l:rr] # else copy rest of left run
return # and return
自下而上的合并排序仅稍快一些,但对于此版本,如果通过次数为奇数,它将在第一次通过时交换到位,这将进一步帮助您。合并功能(mrg)与上面显示的自上而下的合并排序相同。
def sort(a):
if(len(a) < 2): # if nothing to do, return
return
b = [0] * len(a) # allocate b
mrgsrt(a, b, len(a))
def mrgsrt(a, b, n):
s = 1 # assume even pass count
if((passcnt(n) & 1) == 1): # if odd count
while(s < n): # swap pairs in place
if(a[s] < a[s-1]):
a[s-1],a[s] = a[s],a[s-1]
s = s + 2
s = 2
while(s < n):
ee = 0 # reset end index
while(ee < n): # setup for next pair of runs
ll = ee
rr = ll + s
if(rr >= n): # if only left run copy it
b[ll:n] = a[ll:n]
break
ee = rr + s
if(ee > n):
ee = n
mrg(a, b, ll, rr, ee)
a,b = b,a # swap(a, b)
s = s << 1 # double run size
def mrg(a, b, ll, rr, ee): # merge a pair of runs from a to b
o = ll # o = b[] index
l = ll # l = a[] left index
r = rr # r = a[] right index
while True:
if(a[l] <= a[r]): # if a[l] <= a[r]
b[o] = a[l] # copy a[l]
o += 1
l += 1
if(l < rr): # if not end of left run
continue # continue (back to while)
b[o:ee] = a[r:ee] # else copy rest of right run
return # and return
else: # else a[l] > a[r]
b[o] = a[r] # copy a[r]
o += 1
r += 1
if(r < ee): # if not end of right run
continue # continue (back to while)
b[o:ee] = a[l:rr] # else copy rest of left run
return # and return
def passcnt(n): # return # passes
i = 0
s = 1
while(s < n):
s = s << 1
i = i + 1
return(i)
更快地仍然是混合插入+合并排序,对运行<= 64个元素使用插入排序(取决于元素大小)。我没有python代码作为示例。由于python具有解释性,因此速度较慢,在上面显示的示例合并排序中,python所需的时间大约是用C ++编译的相同代码的64倍。