分治法实现归并排序
分治法简介:
分治法从字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或者更多相同或者相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。归并排序算法也是简历在分治法的操作上实现的算法,归并排序将一个序列分成多个子序列,将所有子序列有序,再将有序的子序列合并,得到排好序的序列。
归并排序基本原理:
(1) 递归将问题分解,将序列元素大于等于3个的时候,将数组分为两个更小的数组并继续判断元素个数进行划分。
(2) 解决小规模的问题,如序列中只有一个或者两个元素的时候,将小规模问题进行排序。
(3) 依次将小规模的问题进行合并,每次得到比小规模问题大一倍的规模的有序序列。
(4) 最后规模扩大到原问题的规模时,得到的序列便是排好序的有序序列。
归并排序关键代码思想:
(1) 归并过程的实现,定义一个归并函数并且传入三个参数,传入序列,左端点下标和右端点下标。对序列进行平均划分,将两个序列中较小元素的值先进行比较存放到一个临时序列,再将未比较的值进行依次传入临时序列,最后将临时列表重新赋给传入参数列表。
(2) 分治操作实现,定义一个分治函数,传入三个参数,传入序列,左端点以及右端点下标。对序列长度进行判断,如果序列长度大于等于1时,继续进行划分,如果序列长度小于1,就停止划分,最后再实现由局部到整体的合并。
(3) python3.6版本中的输入默认为字符串,因此输入序列采用split()函数对输入的字符串以“ ”为界进行分离取值,再将其存放到一个数组中。注意存放到数组中时,每个元素都还是字符串,利用强制转换将每个元素转换为int型,再将其append到数组中。
(4) 计算程序运行时间,导入python自带的time模块,采用模块中的clock函数,在归并排序前后分别调用clock函数记录时间,最后两个时间值作差值,得到归并排序算法实现的运行时间。
归并具体实例分析:
假如给定序列5 3 4 6 8 1 7 9,利用上述思想对序列进行排序。
(1)先将序列进行划分为细小的模块
首先原始数列传入:5 3 4 6 8 1 7 9,第一组合并还未进行。
第一次划分:5 3 4 6 || 8 1 7 9,第二组合并还未进行。
第二次划分:5 3 || 4 6 || 8 1 || 7 9,第三组合并还未进行。
(2) 因为每组元素序列个数已经小于等于2,因此开始进行合并操作
进行第三组合并:5 3 || 4 6 || 8 1 || 7 9 ——> 3 5 || 4 6 || 1 8 || 7 9
进行第二组合并:3 5 4 6 || 1 8 7 9 ——> 3 4 5 6 || 1 7 8 9
进行第一组合并: 3 4 5 6 || 1 7 8 9 ——> 1 3 4 5 6 7 8 9
最终得到的序列便为已经排好序的有序序列。
归并排序代码的具体实现:
import time
def hebin(arr,left,right):
mid = int((right - left)/2 + left)
temp = []
i = left
j = mid + 1
while i<mid+1 and j<right+1:
if arr[i]>arr[j]:
temp.append(arr[j])
j+=1
else:
temp.append(arr[i])
i+=1
while i<mid+1:
temp.append(arr[i])
i+=1
while j<right+1:
temp.append(arr[j])
j+=1
mm = 0
for tt in range(left,right+1):
arr[tt] = temp[mm]
mm+=1
def fenzhi(arr,left,right):
if right - left<1:
return 0
else:
mid = int((right - left)/2 + left)
fenzhi(arr,left,mid)
fenzhi(arr,mid+1,right)
hebin(arr,left,right)
def main():
a=[]
t = input().split(" ")
time1 = time.clock()
for tt in t:
a.append(int(tt))
left = 0
right = len(a) - 1
fenzhi(a,left,right)
time2 = time.clock()
for n in a:
print(n ,end = " ")
print("\n程序运行时间:%f"%(time2 - time1))
if __name__ == '__main__':
main()
测试记录:
注意事项:
进行输入序列操作时,输入的序列元素之间有且只能有一个空格隔开,并且在序列末尾不能含有空格,否则程序会报错。