归并排序:就是将列表里面每个元素看成一个列表,这样单个元素就是有序的,然后将相邻两个列表归并。
归并:归并就是将两个有序的序列变成一个列表
第一步:定义归并
我们可以举一个例子,将列表分为两段有序序列将两端进行归并
def merge(li,low,mid,high):
i = low
j = mid + 1
tmp =[]
# 这里将一个列表分为两段有序的队列,mid为分隔线
while i <= mid and j <= high:
# 只有左右两边都有数那就进行比较
if li[i] <= li[j]:
tmp.append(li[i])
i += 1
else:
tmp.append(li[j])
j += 1
# 此时当while循环执行完之后 两段有序列表肯定有一边已经全部添加到tmp(临时列表)里面,肯定有一边还剩下一部分,要将剩下的部分
# 直接添加到tmp中就可以了
# 先判断那一部分还有数据
while i <= mid:
tmp.append(li[i])
i += 1
while j <= high:
tmp.append(li[j])
j +=1
li[low:high+1] = tmp
首先把列表分成两段,分别是从2开始到9,和从1到3.那么9就是mid,结合代码 j - mid就是前半部分,(mid+1)到 high就是后半段。
这里i和j就是两个指针 首先我么要确定两部分都有元素才会进行比较,如果任何一部分没有元素的时候我们就停止循环,因为两部分都是有序的所以可以遍历每一部分进行比较。将比较结果添加到临时存储列表tmp中。当遍历完所有的数时肯定有一部分是剩余的,而另一部分已经没有元素了,但是剩下的数肯定是最大的,结合例子来看,最后前半部分的7,8就是剩余的元素。我们直接将剩余的元素添加进列表里。然后列表切片将数据再次写回去,这时候整个列表就有排好序了。这个操作就是归并。
2.归并排序
在一个无序的列表里面只要将列表里面每一个元素看成一个序列,那么每一个序列就是有序的,然后每两个相邻序列进行归并,然后这时候每个序列就有两个元素并且每个序列都是有序的,然后每两个相邻的两个序列在进行归并,归并完之后就变成有四个数的有序序列,然后再次进行归并,以此类推,直到归并成整个有序的列表。如图
然后我们用代码写出来,这里就要用到递归的思想。我们将列表看成两部分分别是左边和右边,我们分别归并左边和右边,然后再归并整个列表。
def merge_sort(li,low,high):
'''
:param li: 无序的列表
:param low: 第一个元素的下标
:param high: 最后一个元素的下标
:return:
'''
# 这里用递归的思想,将整个归并看成只需要分别归并列表的左边与右边,当左边和右边都变成有序的之后在进行整个列表的归并
if low < high:
mid = (low + high) // 2
# 归并左边
merge_sort(li,low,mid)
# 归并右边
merge_sort(li,mid+1,high)
# 归并整个列表
merge(li,low,mid,high)
这就是我个人理解的归并排序,仅为个人理解。