实验内容
给定任意几组数据,利用分治法的思想,将数据进行排序并将排好的数据进行输出。
实验原理
利用分治法,将一个数组元素大于 2 的数组分成两个子数组,然后对每一个子数组递归调用,直到最下的子数组的元素个数为 1,此时子数组就不用进行排序了,再往上回溯,依据每个子数组中的元素大小对子数组进行合并,依次进行下去,最后返回的数组就是一个依据数组元素大小排序好的数组。
实验步骤
① 先解决小规模的问题,如数组中只有 1 个元素的情况。
② 将问题分解,如果数组的元素大于等于 2个,将数组分为两个小的数组。
③ 递归的解各子问题,将中分解的两个小的数组再进行以上两个步骤最后都化为小规模问题。
④ 将各子问题的解进行比较最终得到原问题的解。
代码实现
import time
def mergesort(A): #递归直到子数组元素个数少于1
if len(A) <= 1:
return A
mid = len(A) // 2
result1 = mergesort(A[:mid])
result2 = mergesort(A[mid:])
return merge(result1, result2)
def merge(A, B): #依据子数组元素大小合并子数组
result = []
i = j = 0
while i < len(A) and j < len(B):
if A[i] < B[j]:
result.append(A[i])
i += 1
else:
result.append(B[j])
j += 1
if i == len(A):
while j < len(B):
result.append(B[j])
j += 1
else:
while i < len(A):
result.append(A[i])
i += 1
return result
def main():
from random import sample
rand_array = sample([x for x in range(-500, 500)], 10)
print(rand_array)
start = time.time()
result = mergesort(rand_array)
print(result)
end = time.time()
print("共耗时:\n" + str(end - start) + " s")
if __name__ == '__main__':
main()
时间复杂度分析
上述代码中,每次将每个数组分成两个子数组,最后进行合并,因此我们可以得到递归式:
T(n) = 2T(n/2) + n,依据主定理法得出该算法的时间复杂度为 O(nlgn)
运行结果
[-482, -435, 473, -368, -28, -50, 37, -169, 488, -388]#排序前
[-482, -435, -388, -368, -169, -50, -28, 37, 473, 488]#排序后
共耗时:
0.0 s
[188, 380, -432, 119, -230, 258, -190, 156, 194, -110]#排序前
[-432, -230, -190, -110, 119, 156, 188, 194, 258, 380]#排序后
共耗时:
0.0 s
[178, -171, 293, -90, 168, 87, 375, -11, 270, -331]#排序前
[-331, -171, -90, -11, 87, 168, 178, 270, 293, 375]#排序后
共耗时:
0.0 s