【数据结构】TOP-K问题/使用堆解决

简介: 文章目录TOP-K问题一、题目描述二、 思路:三、代码实现1.随机产生一万个数据,存入文件中。2.找前K个最大值3.测试类:四、时间复杂度和空间复杂度分析TOP-K问题

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤

📃个人主页 :阿然成长日记 👈点击可跳转

📆 个人专栏: 🔹数据结构与算法🔹C语言进阶

🚩 不能则学,不知则问,耻于问人,决无长进

🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

TOP-K问题

一、题目描述

假设有一亿个数据,内存存储不下,而我们只需要这一亿个数据中最大的前K个。

二、 思路:

1.:存前K个数据入堆

从第二个开始,每存储一个数据进来,就对其进行向上调整,使其一直保持为小堆。直到k-1个节点停止存储。

2.再从第K+1个数据开始读取

此时读取的数据就不再往堆中插入了,而是与堆顶元素进行比较,如果比堆顶大,那么就替换堆顶元素,然后进行基于小堆的向下调整。

3.所有数据读取完毕,堆中剩余的K个就是最大的K个数据

三、代码实现

1.随机产生一万个数据,存入文件中。

void CreateNDate()
{
  // 造数据
  int n = 10000000;
  srand(time(0));
  const char* file = "data.txt";
  FILE* fin = fopen(file, "w");
  if (fin == NULL)
  {
    perror("fopen error");
    return;
  }
  for (int i = 0; i < n; ++i)
  {
    int x = (rand() + i) % 10000000;
    fprintf(fin, "%d\n", x);
  }
  fclose(fin);
}

2.找前K个最大值

void PrintTopK(const char* filename, int k)
{
 建堆/用a中前k个元素建堆
  FILE* fout = fopen(filename, "r");
  if (fout == NULL)
  {
    perror("fopen fail");
    return;
  }
开辟K个元素空间
  int* minheap = (int*)malloc(sizeof(int) * k);
  if (minheap == NULL)
  {
    perror("malloc fail");
    return;
  }
将前k个元素读入数组minheap
  for (int i = 0; i < k; i++)
  {
    fscanf(fout, "%d", &minheap[i]);
  }
 用前k个数建小堆,使用从下到上的向下调整方法建堆。
k-1下标的双亲节点是(k-1-1)/2;
  for (int i = (k - 2) / 2; i >= 0; --i)
  {
    AdjustDown(minheap, k, i);
  }
将剩余n-k个元素依次与堆顶元素交换,不满足,则替换
  int x = 0;
  while (fscanf(fout, "%d", &x) != EOF)
  {
    if (x > minheap[0])
    {
替换堆顶元素进堆
      minheap[0] = x;
并且进行调整
      AdjustDown(minheap, k, 0);
    }
  }
遍历完所有n个数据后,打印出堆中的数据,就是最大的K个数据啦!
  for (int i = 0; i < k; i++)
  {
    printf("%d ", minheap[i]);
  }
  printf("\n");
  fclose(fout);
}
// fprintf  fscanf

3.测试类:

int main()
{
  //CreateNDate();
  PrintTopK("data.txt", 5);
  return 0;
}

四、时间复杂度和空间复杂度分析

🔸时间复杂度:O(N*logK);

N:节点个数。K:最大的前K个个数

如果N>>K,那么可以认为时间复杂度是O(N);这也是此算法的厉害之处。

🔸空间复杂度:O(K);

K:最大的前K个个数.

相关文章
|
7天前
|
算法 安全 大数据
揭秘!Python堆与优先队列:数据结构的秘密武器,让你的代码秒变高效战士!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能,助你提升算法效率。堆用于快速找大数据集的第K大元素,如示例所示,时间复杂度O(n log k)。PriorityQueue在多线程中智能调度任务,如模拟下载管理器,按优先级处理任务。掌握这些工具,让代码运行更高效!
21 1
|
5天前
|
存储 算法 调度
惊呆了!Python高级数据结构堆与优先队列,竟然能这样优化你的程序性能!
【7月更文挑战第10天】Python的heapq模块实现了堆和优先队列,提供heappush和heappop等函数,支持O(log n)时间复杂度的操作。优先队列常用于任务调度和图算法,优化性能。例如,Dijkstra算法利用最小堆加速路径查找。堆通过列表存储,内存效率高。示例展示了添加、弹出和自定义优先级元素。使用堆优化程序,提升效率。
15 2
|
14天前
|
存储 缓存 算法
堆和栈的区别及应用场景
堆和栈的区别及应用场景
|
20天前
|
存储 测试技术
【数据结构】详解堆的实现
【数据结构】详解堆的实现
18 4
|
1月前
数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)
数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)
13 1
数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)
|
7天前
|
算法 安全 调度
逆天改命!Python高级数据结构堆(Heap)与优先队列,让你的算法效率飙升至宇宙级!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue实现了堆和优先队列,提供高效算法解决方案。堆用于Dijkstra算法求解最短路径,例如在图论问题中;PriorityQueue则在多线程下载管理中确保高优先级任务优先执行。这两个数据结构提升效率,简化代码,是编程中的强大工具。
10 0
|
7天前
|
安全 调度 Python
Python堆与优先队列:不只是数据结构,更是你编程路上的超级加速器!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能。堆,作为完全二叉树,支持排序性质,heapq用于单线程操作;PriorityQueue在多线程中保证安全。通过示例展示了如何插入、删除任务,以及在多线程任务调度中的应用。堆与优先队列是高效编程的关键工具,提升代码性能与并发处理能力。
9 0
|
7天前
|
存储 算法 安全
解锁Python高级数据结构新姿势:堆与优先队列的实战演练,让你的代码更优雅!
【7月更文挑战第8天】Python的`heapq`模块和`queue.PriorityQueue`提供堆与优先队列功能,用于高效数据管理。堆是完全二叉树,`heapq`实现最小堆,常用于任务调度,如按优先级执行任务。当需要线程安全且更复杂操作时,`queue.PriorityQueue`成为优选,例如在管理网络请求时按优先级处理。这两个数据结构能提升代码效率和可读性。
|
1月前
|
存储
数据结构初阶 堆(一)
数据结构初阶 堆(一)
18 1
|
13天前
|
存储 缓存 算法
堆和栈的区别及应用场景
堆和栈的区别及应用场景