归并排序之python
归并排序( Merge sort),也成合并排序、二分排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
1.算法描述:
- 分而治之
- 分 :
- 递归地拆分数组,直到它被分成两对单个元素数组为止.
- 然后,将这些单个元素中的每一个与它的对合并,然后将这些对与它们的对等合并, 直到整个列表按照排序顺序合并为止.
- 治 :
- 将2个排序列表合并为另一个排序列表是很简单的.
- 简单地通过比较每个列表的头,删除最小的,以加入新排序的列表.
- O(n) 操作
2.算法属性:
- 时间复杂度:O(nlogn)
- 空间复杂度:O(1)
- 稳定性:稳定
3.代码实现
''' 名字很多:归并排序/合并排序/二分排序 算法时间复杂度 O(logn) 递归 两个步骤:1.拆分 2.合并 ''' def merge_sort(nums=list): #取mid以及左右两个数组 mid = len(nums)//2 left_nums,right_nums = nums[:mid],nums[mid:] #递归分治 if len(left_nums) > 1: left_nums = merge_sort(left_nums) if len(right_nums) > 1: right_nums = merge_sort(right_nums) #合并 res = [] while left_nums and right_nums: #两个都不为空的时候 if left_nums[-1] >= right_nums[-1]: #尾部较大者 res.append(left_nums.pop()) else: res.append(right_nums.pop()) res.reverse() #倒序 return (left_nums or right_nums) + res #前面加上剩下的非空nums lis = [7, 5, 0, 6, 3, 4, 1, 9, 8, 2] print(merge_sort(lis)) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#学习版本 #递归 #两个步骤:1.拆分 2.合并 def _merge(a: list, b: list) -> list: #合并两个排序表 c = [] while len(a) > 0 and len(b) > 0: if a[0] < b[0]: c.append(a[0]) a.remove(a[0]) else: c.append(b[0]) b.remove(b[0]) if len(a) == 0: c += b else: c += a return c def _merge_sorted(nums: list) -> list: # Won't sort in place if len(nums) <= 1: return nums m = len(nums) // 2 a = _merge_sorted(nums[:m]) #前半 b = _merge_sorted(nums[m:]) #后半 return _merge(a, b) # Wrapper包装器 def merge_sorted(nums: list, reverse=False) -> list: import time start = time.time() #归并排序 nums = _merge_sorted(nums) if reverse: nums = nums[::-1] t = time.time() - start return nums, len(nums), t lis = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] merge_sorted(l, reverse=False)[0] #输出结果 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Github地址:https://github.com/kumataahh