news 2026/5/17 5:53:14

Python实现归并排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python实现归并排序

Python实现归并排序

defmerge_sort_recursive(arr):""" 归并排序 - 递归实现(最经典版本) 时间: O(n log n) 空间: O(n) - 需要额外数组存储合并结果 """iflen(arr)<=1:returnarr# 1. 分割:找到中间点mid=len(arr)//2# 2. 递归排序左右两半left=merge_sort_recursive(arr[:mid])right=merge_sort_recursive(arr[mid:])# 3. 合并两个有序数组returnmerge(left,right)defmerge(left,right):"""合并两个有序数组"""result=[]i=j=0# 比较两个数组的元素,依次放入结果whilei<len(left)andj<len(right):ifleft[i]<=right[j]:result.append(left[i])i+=1else:result.append(right[j])j+=1# 添加剩余元素result.extend(left[i:])result.extend(right[j:])returnresultdefmerge_sort_inplace(arr,left=0,right=None):""" 归并排序 - 原地版本(不创建新数组切片) 更节省内存,但实现稍复杂 """ifrightisNone:right=len(arr)-1ifleft<right:mid=(left+right)//2# 递归排序左右两半merge_sort_inplace(arr,left,mid)merge_sort_inplace(arr,mid+1,right)# 合并两个有序部分merge_inplace(arr,left,mid,right)defmerge_inplace(arr,left,mid,right):"""原地合并两个有序部分"""# 创建临时数组存储左右部分left_part=arr[left:mid+1]right_part=arr[mid+1:right+1]i=j=0k=left# 合并whilei<len(left_part)andj<len(right_part):ifleft_part[i]<=right_part[j]:arr[k]=left_part[i]i+=1else:arr[k]=right_part[j]j+=1k+=1# 复制剩余元素whilei<len(left_part):arr[k]=left_part[i]i+=1k+=1whilej<len(right_part):arr[k]=right_part[j]j+=1k+=1defmerge_sort_iterative(arr):""" 归并排序 - 迭代版本(自底向上) 避免递归调用,适合超大数据 """n=len(arr)# 当前子数组大小,从1开始,每次翻倍size=1whilesize<n:# 合并相邻的大小为size的子数组forleftinrange(0,n,size*2):mid=min(left+size-1,n-1)right=min(left+size*2-1,n-1)ifmid<right:merge_inplace(arr,left,mid,right)size*=2returnarrdefmerge_sort_with_steps(arr):""" 带步骤输出的归并排序 - 用于理解和调试 """print(f"初始数组:{arr}")print("="*50)defmerge_with_log(left,right,depth=0):indent=" "*depthprint(f"{indent}分割:{left}|{right}")iflen(left)<=1andlen(right)<=1:result=sorted(left+right)print(f"{indent}合并:{left}+{right}={result}")returnresult# 继续分割iflen(left)>1:mid_left=len(left)//2left=merge_with_log(left[:mid_left],left[mid_left:],depth+1)iflen(right)>1:mid_right=len(right)//2right=merge_with_log(right[:mid_right],right[mid_right:],depth+1)# 合并result=[]i=j=0whilei<len(left)andj<len(right):ifleft[i]<=right[j]:result.append(left[i])i+=1else:result.append(right[j])j+=1result.extend(left[i:])result.extend(right[j:])print(f"{indent}合并:{left}+{right}={result}")returnresult result=merge_with_log(arr[:len(arr)//2],arr[len(arr)//2:])print("="*50)print(f"排序结果:{result}")returnresultdefmerge_sort_generator(arr):""" 生成器版本 - 可以逐步获取排序过程中的状态 适合可视化 """iflen(arr)<=1:yieldarrreturnmid=len(arr)//2left_gen=merge_sort_generator(arr[:mid])right_gen=merge_sort_generator(arr[mid:])left=next(left_gen)right=next(right_gen)# 逐步合并result=[]i=j=0whilei<len(left)andj<len(right):ifleft[i]<=right[j]:result.append(left[i])i+=1else:result.append(right[j])j+=1yieldresult+left[i:]+right[j:]result.extend(left[i:])result.extend(right[j:])yieldresult# ============================================# 测试代码# ============================================deftest_merge_sort():"""测试各种归并排序实现"""test_cases=[[64,34,25,12,22,11,90],[5,2,4,6,1,3],[1,2,3,4,5],# 已排序[5,4,3,2,1],# 逆序[1],# 单元素[],# 空数组[3,3,3,3],# 重复元素]print("="*60)print("测试归并排序实现")print("="*60)fori,testinenumerate(test_cases,1):print(f"\n测试用例{i}:{test}")# 递归版本arr1=test.copy()result1=merge_sort_recursive(arr1)print(f" 递归版本:{result1}")# 原地版本arr2=test.copy()merge_sort_inplace(arr2)print(f" 原地版本:{arr2}")# 迭代版本arr3=test.copy()merge_sort_iterative(arr3)print(f" 迭代版本:{arr3}")# 验证正确性expected=sorted(test)assertresult1==expected,f"递归版本错误:{result1}!={expected}"assertarr2==expected,f"原地版本错误:{arr2}!={expected}"assertarr3==expected,f"迭代版本错误:{arr3}!={expected}"print("\n"+"="*60)print("✓ 所有测试通过!")print("="*60)defdemo_step_by_step():"""演示逐步执行的归并排序"""print("\n"+"="*60)print("逐步演示归并排序")print("="*60)arr=[38,27,43,3,9,82,10]print(f"\n原始数组:{arr}\n")# 使用带步骤输出的版本merge_sort_with_steps(arr)defdemo_generator():"""演示生成器版本 - 逐步获取排序状态"""print("\n"+"="*60)print("生成器版本 - 逐步获取排序状态")print("="*60)arr=[38,27,43,3,9,82,10]print(f"原始数组:{arr}\n")gen=merge_sort_generator(arr)step=1forstateingen:print(f"步骤{step}:{state}")step+=1# ============================================# 性能对比# ============================================defperformance_comparison():"""比较不同实现的性能"""importtimeimportrandom sizes=[100,1000,5000,10000]print("\n"+"="*60)print("性能对比 (秒)")print("="*60)print(f"{'大小':<8}{'递归版本':<12}{'原地版本':<12}{'迭代版本':<12}")print("-"*50)forsizeinsizes:arr=[random.randint(1,10000)for_inrange(size)]# 递归版本arr1=arr.copy()start=time.time()merge_sort_recursive(arr1)time_recursive=time.time()-start# 原地版本arr2=arr.copy()start=time.time()merge_sort_inplace(arr2)time_inplace=time.time()-start# 迭代版本arr3=arr.copy()start=time.time()merge_sort_iterative(arr3)time_iterative=time.time()-startprint(f"{size:<8}{time_recursive:<12.4f}{time_inplace:<12.4f}{time_iterative:<12.4f}")# ============================================# 实用工具函数# ============================================defis_sorted(arr):"""检查数组是否已排序"""returnall(arr[i]<=arr[i+1]foriinrange(len(arr)-1))defget_operation_count(arr):""" 统计归并排序的操作次数 用于演示 O(n log n) 复杂度 """operations={'comparisons':0,'merges':0}defcount_merge(left,right):operations['merges']+=1result=[]i=j=0whilei<len(left)andj<len(right):operations['comparisons']+=1ifleft[i]<=right[j]:result.append(left[i])i+=1else:result.append(right[j])j+=1result.extend(left[i:])result.extend(right[j:])returnresultdefcount_sort(arr):iflen(arr)<=1:returnarr mid=len(arr)//2left=count_sort(arr[:mid])right=count_sort(arr[mid:])returncount_merge(left,right)count_sort(arr.copy())returnoperations# ============================================# 主程序# ============================================if__name__=="__main__":# 运行测试test_merge_sort()# 演示逐步执行demo_step_by_step()# 演示生成器demo_generator()# 性能对比performance_comparison()# 统计操作次数演示 O(n log n)print("\n"+"="*60)print("验证 O(n log n) 复杂度")print("="*60)sizes=[10,100,1000,5000]forsizeinsizes:arr=list(range(size,0,-1))# 逆序数组(最坏情况)ops=get_operation_count(arr)n_log_n=size*(size.bit_length()-1)# 近似 n * log2(n)print(f"n={size:<5}: 比较次数={ops['comparisons']:<6}"f"合并次数={ops['merges']:<4}"f"n*log2(n)≈{n_log_n}")

主要特点:

1.四种实现方式

  • merge_sort_recursive: 递归版本(最直观)
  • merge_sort_inplace: 原地版本(省内存)
  • merge_sort_iterative: 迭代版本(无递归)
  • merge_sort_generator: 生成器版本(逐步输出)

2.辅助功能

  • 逐步执行演示
  • 性能对比测试
  • 操作次数统计(验证 O(n log n))
  • 完整的测试用例

3.核心要点

  • 分治思想:分割 → 排序 → 合并
  • 稳定性:相等元素保持原顺序
  • 空间复杂度:O(n) 需要额外空间
  • 时间复杂度:O(n log n) 始终如一
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/17 5:52:06

Pandrator:轻量级Web请求逆向工具,高效破解复杂数据接口

1. 项目概述&#xff1a;一个开源的“潘多拉魔盒”解锁器最近在折腾一些自动化脚本和数据处理工具时&#xff0c;偶然在GitHub上发现了一个名为“Pandrator”的项目。这个由开发者lukaszliniewicz创建的工具&#xff0c;名字本身就很有意思&#xff0c;结合了“Pandora”&#…

作者头像 李华
网站建设 2026/5/17 5:49:41

基于Circuit Playground Express与NeoPixel的四季交互灯光装置设计与实现

1. 项目概述与核心思路几年前&#xff0c;我在一个艺术展上看到一组悬挂在枯树枝上的玻璃瓶&#xff0c;里面装着会呼吸般变幻光线的LED灯&#xff0c;那种静谧又灵动的美感让我念念不忘。作为一个喜欢把代码和电路“藏”进生活场景里的硬件爱好者&#xff0c;我一直在琢磨如何…

作者头像 李华
网站建设 2026/5/17 5:49:40

数据中心碳减排:工作负载迁移与服务器调度优化

1. 数据中心碳减排技术概述 在数字经济时代&#xff0c;数据中心作为信息基础设施的核心载体&#xff0c;其能源消耗和碳排放问题日益凸显。据统计&#xff0c;全球数据中心电力消耗已占全球总用电量的1-2%&#xff0c;且随着AI、云计算等技术的快速发展&#xff0c;这一比例仍…

作者头像 李华
网站建设 2026/5/17 5:48:03

Metaclaw:为AI多智能体系统构建声明式规则治理框架

1. 项目概述&#xff1a;一个面向元认知的“法律”框架 最近在探索AI Agent和复杂系统设计时&#xff0c;我遇到了一个非常有意思的项目&#xff1a; mverab/metaclaw 。初看这个标题&#xff0c;可能会让人有些困惑——“meta”和“law”组合在一起&#xff0c;听起来像是一…

作者头像 李华
网站建设 2026/5/17 5:47:08

Awesome-GPTs:社区驱动的AI应用精选库使用与贡献指南

1. 项目概述与核心价值最近在GitHub上闲逛&#xff0c;发现了一个名为“Awesome-GPTs”的项目&#xff0c;热度相当高。作为一个长期关注AI应用落地的从业者&#xff0c;我立刻被这个仓库吸引了。简单来说&#xff0c;这是一个由社区驱动的、专门收集和整理各类GPTs&#xff08…

作者头像 李华