python_归并排序
归并排序
归并: 假设现在列表分为两段有序,如何将其合为一个有序列表。这种操作叫一次归并。
【2,5,7,8,9】 【1,3,4,6】
归并排序不能原地改,只能拿一个新列表存储,所以会有一个空间复杂度。
排序思路
时间复杂度
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
空间复杂度
O
(
n
)
O(n)
O(n)
排序思路:
- 1、分解:将列表越分越小,直到分成一个元素。
- 2、终止条件:一个元素是有序的。
- 3、合并:将两个有序列表归并,列表越来越大
实现
一次归并(merge实现)
def merge(li,low,mid,high): #分成两断,low到mid一段,mid+1到high为另一段
i = low
j = mid +1 #i,j为定义的两个箭头,指向两个有序列表的第一个元素
ltmp =[]
while i<=mid and j <=high: #只要左右两边都有数
if li[i] < li[j]:
ltmp.append(li[i]) #
i += 1
else :
ltmp.append(li[j]) #
j += 1
#while执行完成,肯定有一部分没数,但是是哪边不知道。
while i <=mid: #左边列表还有数
ltmp.append(li[i])
i += 1
while j <=high: #右边列表还有数
ltmp.append(li[j])
j += 1
#将ltmp中的值写回到li,切片
li[low:high+1] =ltmp
li =[2,5,6,8,9,1,3,4,7]
print(li)
merge(li,0,len(li)//2 ,len(li)-1)
#merge(li,0,4,8)
print(li)
####################输出:#########################
[2, 5, 6, 8, 9, 1, 3, 4, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序实现
def merge_sort(li,low,high):
if low < high :#至少有两个元素
#归并左边、归并右边、左右两边merge
mid = (low+high)//2
merge_sort(li,low,mid)
merge_sort(li,mid+1,high)
merge(li,low,mid,high)
li =list(range(100))
import random
random.shuffle(li)
print(li)
merge_sort(li,0,len(li)-1)
print(li)
####################输出:#########################
[68, 44, 77, 51, 92, 26, 33, 99, 11, 55, 36, 28, 43, 84, 70, 18, 73, 67, 63, 69, 96, 29, 32, 72, 52, 76, 74, 61, 16, 53, 45, 35, 23, 93, 54, 31, 3, 57, 50, 22, 5, 56, 71, 95, 97, 6, 83, 14, 42, 15, 24, 85, 1, 49, 39, 20, 90, 58, 27, 65, 12, 0, 66, 37, 46, 87, 88, 91, 64, 19, 82, 7, 62, 13, 8, 48, 30, 94, 38, 17, 47, 59, 86, 81, 79, 75, 41, 10, 98, 40, 78, 89, 80, 4, 21, 2, 60, 9, 25, 34]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]