归并排序分分解和归并两个步骤。分解就是将一组数一级级分解到单个数,归并就是将一组左右都是有序但是合起来无序的数排序。
一、先说归并
上图是一组左右两边都有序,但是合起来无序的数组,对这样的数组进行排序就叫归并。
1、首先确定两个位置标示,即为两个箭头,第一个为low,第二个为high,在排序开始前分别指向左右有序数组的第一个位置,还有一个中间位置mid,这里定义为‘9’的位置。归并函数需要输入(list,low,mid,high)几个参数,list为数组
2、然后分别比较low和high指向位置的数的大小,可以看到high指向的位置为1比2小,将1存放到另一个新建数组的第一个位置,high向右移动加1。
3、重复2的步骤,直到high大于数组长度或者low大于mid
4、当3满足条件时,将剩下的数直接拷贝到新建数组的末端
def merge(list,low,mid,high):
p1 = low
p2 = mid + 1
li = []
while(p1<=mid and p2<=high):
if(list[p1]<list[p2]):
li.append(list[p1])
p1 = p1 + 1
else:
li.append(list[p2])
p2 = p2 + 1
while(p1 <= mid):
li.append(list[p1])
p1 = p1 + 1
while(p2 <= high):
li.append(list[p2])
p2 = p2 + 1
list[low:high+1] = li
二、 分解
上面归并是对左右两边有序的数组进行排序,但是我们要排序的数组并不是两边有序的数组。所以我们需要将其进行分解,如图所示,将数组一级级分解,当分解到只有一个数时就是左右有序的了,因为一个数本身就是有序的。然后我们只需调用上面写的归并函数进行一级级往回归并就可以得到一组有序的数组。
def merge_sort(list,low,high):
if(low < high):
mid = (low + high)//2
merge_sort(list,low,mid)
merge_sort(list,mid+1,high)
merge(list,low,mid,high)
下面是整体代码
def merge(list,low,mid,high):
p1 = low
p2 = mid + 1
li = []
while(p1<=mid and p2<=high):
if(list[p1]<list[p2]):
li.append(list[p1])
p1 = p1 + 1
else:
li.append(list[p2])
p2 = p2 + 1
while(p1 <= mid):
li.append(list[p1])
p1 = p1 + 1
while(p2 <= high):
li.append(list[p2])
p2 = p2 + 1
list[low:high+1] = li
def merge_sort(list,low,high):
if(low < high):
mid = (low + high)//2
merge_sort(list,low,mid)
merge_sort(list,mid+1,high)
merge(list,low,mid,high)
list = [i for i in range(10)]
import random
random.shuffle(list)
print(list)
merge_sort(list,0,9)
print(list)