当前位置: 首页 > news >正文

【数据结构】——外部排序(K路归并)

问题:给你一个20G大小的数组,但是内存只有4G,如何进行排序。 这个问题在面试中出现的还比较高频。

解决方式就是使用归并排序,分批读取这个数组,比如每次读取3个G左右,对这部分数据排序后写到磁盘,然后读取下一批,这样最后大约会有7个小文件,每个小文件内部都有序。

然后加载这7个小文件,用所有小文件的首元素构建一个初始堆,后续利用堆排序每次取堆顶最小元素加入到最终结果,然后从这个堆顶最小元素所在的文件中继续取下一个元素加到堆顶继续堆调整,一直重复直到所有小文件数据都被读取完成。

所以归并排序主要就是用来解决数据远超内存的排序场景,且空间复杂度取决于归并的路数K,跟数据量大小无关。

下面基于python实现对随机生成的7个数组进行7路归并,链表版本的实现可以参考力扣上的这道题解 23. 合并 K 个升序链表:

from typing import Listdef k_way_merge_sort(arrays: List[List[int]]) -> List[int]:def adjust_heap(nums, p, end_idx):while 2 * p + 1 <= end_idx:c = 2 * p + 1if c + 1 <= end_idx and nums[c + 1][0] < nums[c][0]:c += 1if nums[p][0] <= nums[c][0]:breaknums[p], nums[c] = nums[c], nums[p]p = cdef create_heap(nums):last_not_leaf = len(nums) // 2 - 1while last_not_leaf >= 0:adjust_heap(nums, last_not_leaf, len(nums) - 1)last_not_leaf -= 1k_nums = []for idx, arr in enumerate(arrays):if arr:k_nums.append((arr[0], 0, idx))  # (值, 值索引, 子序列索引)if not k_nums:return []create_heap(k_nums)result = []while k_nums:value, value_idx, arr_idx = k_nums[0]result.append(value)if value_idx < len(arrays[arr_idx]) - 1:k_nums[0] = (arrays[arr_idx][value_idx + 1], value_idx + 1, arr_idx)adjust_heap(k_nums, 0, len(k_nums) - 1)else:k_nums[0], k_nums[len(k_nums) - 1] = k_nums[len(k_nums) - 1], k_nums[0]k_nums.pop()if k_nums:adjust_heap(k_nums, 0, len(k_nums) - 1)return resultif __name__ == '__main__':import randomrandom.seed(42)test_arrays = [sorted([random.randint(1, 100) for _ in range(random.randint(0, 10))])for _ in range(7)]  # 随机生成包含7个有序子数组的二维数组for idx, arr in enumerate(test_arrays):print(f'arr{idx}: {arr}')print(f'merge result: {k_way_merge_sort(test_arrays)}')

仅考虑以上单次归并的过程,时间复杂度O(n∗log2k)Ο(n*log_2{k})O(nlog2k),k是总的归并路数,n是总的元素个数。

http://www.dtcms.com/a/397992.html

相关文章:

  • 【观成科技】活跃黑产团伙“黑猫”攻击武器加密通信分析
  • 高斯过程(Gaussian Process)回归:一种贝叶斯非参数方法
  • 微算法科技(NASDAQ MLGO)创新基于账户加权图与后量子密码学的区块链
  • 中国银行信息科技岗位笔试
  • WXML 编译错误修复总结
  • 怎么给网站wordpress游戏网站策划书
  • Halcon学习--(3)图像阈值处理
  • 知识导航新体验:Perplexica+cpolar 24小时智能服务
  • 全面解析Redis分布式锁
  • 自由学习记录(103)
  • 大模型部署基础设施搭建 - Dify
  • 没有网站怎么推广企业建设网站能否报销
  • 天津道路运输安全员考试报名条件
  • dbpystream webapi: 从阿里云福州站点到上海站点的迁移之旅
  • 解读 2025 《可信数据空间 使用控制技术要求》
  • Java多线程编程:阻塞队列、wait-notify锁协调机制、线程安全[条件产生渡送执行]
  • 绕过UAC开机自启动程序方法
  • 东莞市南城装饰工程东莞网站建设系统门窗品牌排行前十名
  • Nginx负载均衡算法与IP透传、跨域实战指南
  • asp.net不适合做网站凡客建设网站稳定吗
  • Vue中的路由细节
  • 高防 IP 是如何帮助数藏行业防刷
  • 将深度学习与Spring Boot集成:使用DL4J构建企业级AI应用的完整指南
  • 《UE5_C++多人TPS完整教程》学习笔记57 ——《P59 脚步声与跳跃声(Footstep And Jump Sounds)》
  • 【Qt】常用控件2——按钮类控件
  • 编程与数学 03-009 Linux 操作系统应用 19_Linux 系统性能监控
  • MQTT通信实现方案(Spring Boot 3 集成MQTT)
  • 做网站客户需求网站建设与运行的盈利收入
  • Sass:CSS 预处理器
  • CSS元素的总宽度计算规则