python的就地合并排序(找不到错误)
我在我的算法书(第三版Cormen算法简介)中读到了关于合并排序(就地)的内容,我决定用Python实现它。问题是我找不到我做错了什么。。。我在C++中看到了一些代码,但是即使是这样我也无法修复它。p> 这是我的密码:python的就地合并排序(找不到错误),python,merge,mergesort,Python,Merge,Mergesort,我在我的算法书(第三版Cormen算法简介)中读到了关于合并排序(就地)的内容,我决定用Python实现它。问题是我找不到我做错了什么。。。我在C++中看到了一些代码,但是即使是这样我也无法修复它。p> 这是我的密码: def MERGE(A,start,mid,end): L=[0]*(mid - start + 1) for i in range(len(L) - 1): L[i] = A[start+i] L[len(L) - 1] = 100000
def MERGE(A,start,mid,end):
L=[0]*(mid - start + 1)
for i in range(len(L) - 1):
L[i] = A[start+i]
L[len(L) - 1] = 100000 # centinel, (fix)
R=[0]*(end - mid + 2)
for j in range(len(R) - 1):
R[j] = A[mid+j]
R[len(R) - 1] = 100000
i = 0
j = 0
k = start
for l in range(k,end):
if(L[i] < R[j]):
A[l] = L[i]
i = i + 1
else:
A[k] = R[j]
j = j + 1
def mergeSort(A,p,r):
if p < r:
mid = int((p+r)/2)
mergeSort(A,p,mid)
mergeSort(A,mid+1,r)
MERGE(A,p,mid,r)
A = [20, 30, 15, 21, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A)]
我知道这可能是一个“愚蠢的问题”,也有一些相关的帖子,但我尝试了其中的建议,它对我不起作用
有人能帮我吗?T
谢谢 此代码工作正常:
def MERGE(A,start,mid,end):
L = A[start:mid]
R = A[mid:end]
i = 0
j = 0
k = start
for l in range(k,end):
if j >= len(R) or (i < len(L) and L[i] < R[j]):
A[l] = L[i]
i = i + 1
else:
A[l] = R[j]
j = j + 1
def mergeSort(A,p,r):
if r - p > 1:
mid = int((p+r)/2)
mergeSort(A,p,mid)
mergeSort(A,mid,r)
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A))
print A
结果如下:
[20, 30, 21, 15] [42, 45, 31, 0, 9]
[20, 30] [21, 15]
[20] [30]
[21] [15]
[42, 45] [31, 0, 9]
[42] [45]
[31] [0, 9]
[0] [9]
这就是我们想要的。但是,“mid+1”会产生无效结果。以下是测试代码:
def MERGE(A,start,mid,end):
# Do nothing
pass
def mergeSort(A,p,r):
if r - p > 1:
mid = int((p+r)/2)
print A[p:mid],A[mid+1:r] # Changed
mergeSort(A,p,mid)
mergeSort(A,mid+1,r) # Changed
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A))
结果:
[20, 30, 21, 15] [45, 31, 0, 9]
[20, 30] [15]
[20] []
[45, 31] [9]
[45] []
(新增) 下面是使用“mid+1”的代码:
# New indexing function that includes the right index.
def get_partial_list(origin_list, left_index, right_index): # Added
return origin_list[left_index:right_index+1]
def MERGE(A,start,mid,end):
L = get_partial_list(A,start,mid)
R = get_partial_list(A,mid+1,end)
i = 0
j = 0
k = start
for l in range(k,end+1): # changed
if j >= len(R) or (i < len(L) and L[i] < R[j]):
A[l] = L[i]
i = i + 1
else:
A[l] = R[j]
j = j + 1
def mergeSort(A,p,r):
if r - p > 0: # changed
mid = int((p+r)/2)
mergeSort(A,p,mid)
mergeSort(A,mid+1,r) # changed
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A)-1) # changed
print A
#包含正确索引的新索引功能。
def get_partial_列表(原点列表、左索引、右索引):#添加
返回原点列表[左索引:右索引+1]
def合并(A、开始、中间、结束):
L=获取部分列表(A、开始、中间)
R=获取部分列表(A,中间+1,结束)
i=0
j=0
k=开始
对于范围内的l(k,结束+1):#更改
如果j>=len(R)或(i0:#更改
mid=int((p+r)/2)
合并排序(A、p、mid)
合并排序(A、mid+1、r)#已更改
合并(A、p、mid、r)
A=[20,30,21,15,42,45,31,0,9]
合并排序(A,0,len(A)-1)#已更改
打印
我添加了新的索引功能。这是您期望的代码吗?此代码工作正常:
def MERGE(A,start,mid,end):
L = A[start:mid]
R = A[mid:end]
i = 0
j = 0
k = start
for l in range(k,end):
if j >= len(R) or (i < len(L) and L[i] < R[j]):
A[l] = L[i]
i = i + 1
else:
A[l] = R[j]
j = j + 1
def mergeSort(A,p,r):
if r - p > 1:
mid = int((p+r)/2)
mergeSort(A,p,mid)
mergeSort(A,mid,r)
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A))
print A
结果如下:
[20, 30, 21, 15] [42, 45, 31, 0, 9]
[20, 30] [21, 15]
[20] [30]
[21] [15]
[42, 45] [31, 0, 9]
[42] [45]
[31] [0, 9]
[0] [9]
这就是我们想要的。但是,“mid+1”会产生无效结果。以下是测试代码:
def MERGE(A,start,mid,end):
# Do nothing
pass
def mergeSort(A,p,r):
if r - p > 1:
mid = int((p+r)/2)
print A[p:mid],A[mid+1:r] # Changed
mergeSort(A,p,mid)
mergeSort(A,mid+1,r) # Changed
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A))
结果:
[20, 30, 21, 15] [45, 31, 0, 9]
[20, 30] [15]
[20] []
[45, 31] [9]
[45] []
(新增) 下面是使用“mid+1”的代码:
# New indexing function that includes the right index.
def get_partial_list(origin_list, left_index, right_index): # Added
return origin_list[left_index:right_index+1]
def MERGE(A,start,mid,end):
L = get_partial_list(A,start,mid)
R = get_partial_list(A,mid+1,end)
i = 0
j = 0
k = start
for l in range(k,end+1): # changed
if j >= len(R) or (i < len(L) and L[i] < R[j]):
A[l] = L[i]
i = i + 1
else:
A[l] = R[j]
j = j + 1
def mergeSort(A,p,r):
if r - p > 0: # changed
mid = int((p+r)/2)
mergeSort(A,p,mid)
mergeSort(A,mid+1,r) # changed
MERGE(A,p,mid,r)
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
mergeSort(A,0,len(A)-1) # changed
print A
#包含正确索引的新索引功能。
def get_partial_列表(原点列表、左索引、右索引):#添加
返回原点列表[左索引:右索引+1]
def合并(A、开始、中间、结束):
L=获取部分列表(A、开始、中间)
R=获取部分列表(A,中间+1,结束)
i=0
j=0
k=开始
对于范围内的l(k,结束+1):#更改
如果j>=len(R)或(i0:#更改
mid=int((p+r)/2)
合并排序(A、p、mid)
合并排序(A、mid+1、r)#已更改
合并(A、p、mid、r)
A=[20,30,21,15,42,45,31,0,9]
合并排序(A,0,len(A)-1)#已更改
打印
我添加了新的索引功能。这是您期望的代码吗?递归地将数组拆分为左右两部分,然后根据您的要求将其合并,即
ASC
或DESC
,检查以下代码:
def merge_sort(a):
if len(a) <= 1:
return a
left = [];
right = [];
mid = len(a)/2
left = a[0:mid]
right = a[mid:(len(a))]
print left
print right
#exit()
left = merge_sort(left)
right = merge_sort(right)
return merge(left, right)
def merge(left, right):
result = []
while len(left) > 0 and len(right) > 0:
lv = left[0]
rv = right[0]
if lv <= rv:
result.append(lv)
left.pop(0)
else:
result.append(rv)
right.pop(0)
while len(left) > 0:
result.append(left.pop(0))
while len(right) > 0:
result.append(right.pop(0))
return result
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
print A
print merge_sort(A)
希望这有助于您理解逻辑。递归地将阵列拆分为左右两部分,然后根据您的要求将其合并,即
ASC
或DESC
,请检查以下代码:
def merge_sort(a):
if len(a) <= 1:
return a
left = [];
right = [];
mid = len(a)/2
left = a[0:mid]
right = a[mid:(len(a))]
print left
print right
#exit()
left = merge_sort(left)
right = merge_sort(right)
return merge(left, right)
def merge(left, right):
result = []
while len(left) > 0 and len(right) > 0:
lv = left[0]
rv = right[0]
if lv <= rv:
result.append(lv)
left.pop(0)
else:
result.append(rv)
right.pop(0)
while len(left) > 0:
result.append(left.pop(0))
while len(right) > 0:
result.append(right.pop(0))
return result
A = [20, 30, 21, 15, 42, 45, 31, 0, 9]
print A
print merge_sort(A)
希望这能帮助你理解逻辑。兰西夫和克里希纳·普拉萨德提供的解决方案没有空间复杂性O(1) 这是Py3的就地合并排序算法,空间复杂度为O(1)。 主功能
sort\u imerge
使用两个辅助功能wmerge
和wsort
此解决方案基于上讨论的C代码:
等等
您还可以使用doctest找到完整的Python代码
def sort\u imerge(Seq,l=0,u=None):
“”“合并排序,可变输入。
输入顺序已更改到位。
时间:O(n*logn)
日志n--级别
n--必须合并每个级别上的元素
空间(附加):O(1)
输入更改到位
不返回
"""
如果u不是其他u,则u=len(Seq)
如果u-l>1:
m=l+(u-l)//2
w=l+u-m
wsort(序号、长、米、西)
当w-l>2时:
n=w
w=l+(n-l+1)//2
wsort(序号、w、n、l)
wmerge(序列,l,l+n-w,n,u,w)
n=w
n>l时:#回退以插入排序
对于范围内的m(n,u):
如果Seq[m-1]>Seq[m]:
序号[m-1],序号[m]=序号[m],序号[m-1]
n-=1
def wmerge(序列号,i,m,j,n,w):
“”“将子阵列[i,m)和[j,n)合并到工作区w中。
所有索引都指向Seq。
w之后的空间必须足够容纳两个子阵列。
"""
当i1:
m=l+(u-l)//2
排序图(序号、l、m)
排序合并(顺序、m、u)
wmerge(序号、l、m、m、u、w)
其他:
而l
lancif和krishna Prasad提供的解决方案没有空间复杂性O(1)
这是Py3的就地合并排序算法,空间复杂度为O(1)。
主功能sort\u imerge
使用两个辅助功能wmerge
和wsort
此解决方案基于上讨论的C代码:
等等
您还可以使用doctest找到完整的Python代码
def sort\u imerge(Seq,l=0,u=None):
“”“合并排序,可变输入。
输入顺序已更改到位。
时间:O(n*logn)