Python实现归并排序

时间:2022-12-22 23:19:47
def mergeSort(seq):  
if len(seq)<=1:
return seq
else:
mid=int(len(seq)//2)
Lpart=mergeSort(seq[:mid])
Rpart=mergeSort(seq[mid:])
return merge(Lpart,Rpart)

def merge(Lpart,Rpart):
newList = list()
a,b=0,0
while a<len(Lpart) and b<len(Rpart):
if Lpart[a]<=Rpart[b]:
newList.append(Lpart[a])
a+=1
else:
newList.append(Rpart[b])
b+=1
while a < len( Lpart ) :
newList.append(Lpart[a])
a+=1
while b < len( Rpart ) :
newList.append(Rpart[b])
b+=1

return newList

if __name__=='__main__':
seq=[23,34,4,5,23,-1,67,55]
print(mergeSort(seq))

mergeSort() 函数提供了一个归并算法的简单的递归实现,但它有几个缺点。首先,它依赖于分片操作,这就阻止了我们使用这个函数来给数组排序,因为数组结构没有提供分片操作。第二,每次递归调用时列表被划分,都创建新的物理子列表。 而分片是一个耗时操作,因为必须创建一个新的列表,把分片的内容从初始列表复制过去。
每次两个子列表合并时又要创建一个新列表,整个处理过程增加了更过时间。
最后,排好序的列表没有被包含进传给函数的同一个初始列表中。

一个更好的实现

# 使用归并排序升序排序一个数组或列表
def mergeSort( theSeq ):
n = len( theSeq )
# 创建合并子序列时使用的临时数组
tmpArray = Array( n )
# 调用私有的递归合并排序函数
recMergeSort( theSeq, 0, n-1, tmpArray )


#使用归并排序按升序排序一个虚拟子序列
def recMergeSort( theSeq, first, last, tmpArray ):
# 比较虚拟子序列的元素由范围[first...last]指定
# tmpArray 在归并排序算法的合并阶段用来做临时存储

# 检查基本情况: 虚拟序列只包含单一项
if first == last :
return;
else :
# 计算出中间点
mid = (first + last) // 2

# 分开序列并执行递归
recMergeSort( theSeq, first, mid, tmpArray )
recMergeSort( theSeq, mid+1, last, tmpArray )

# 合并两个排好序的子序列
mergeVirtualSeq( theSeq, first, mid+1, last+1, tmpArray )
# 合并两个排好序的虚拟子序列: [left..right) [right..end)
# 使用tmpArray 做中间存储.

def mergeVirtualSeq( theSeq, left, right, end, tmpArray ):
# 初始化两个子序列索引变量
a = left
b = right
# 为合并完的结果数组初始化一个索引变量
m = 0
# 合并两个序列直到其中一个为空.
while a < right and b < end :
if theSeq[a] < theSeq[b] :
tmpArray[m] = theSeq[a]
a += 1
else :
tmpArray[m] = theSeq[b]
b += 1
m += 1

# 如果左边的子序列包含更多的项则把它们追加到tmpArray.
while a < right :
tmpArray[m] = theSeq[a]
a += 1
m += 1

# 如果左边的子序列包含更多的项则把它们追加到tmpArray
while b < end :
tmpArray[m] = theSeq[b]
b += 1
m += 1

# 把排好序的子序列复制回初始序列中
for i in range( end - left ):
theSeq[i+left] = tmpArray[i]