<TOP-K问题>《数据结构(C语言版)》

简介: <TOP-K问题>《数据结构(C语言版)》

目录

《数据结构(C语言版)》实战项目之<TOP-K问题>

                                                                            ——By 作者:新晓·故知

问题导引:

思路:

编程实现:

后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

                                                                          ——By 作者:新晓·故知


《数据结构(C语言版)》实战项目之<TOP-K问题>

                                                                            ——By 作者:新晓·故知

问题导引:

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)

最佳的方式就是用堆来解决,基本思路如下:

1. 用数据集合中前K个元素来建堆

k个最大的元素,则建小堆

k个最小的元素,则建大堆

2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

思路:

1.排序:时间复杂度:O(N*logN)  空间复杂度:O(1)

2.建立N个数的大堆,popK次,就可以选出最大的前K个

时间复杂度:O(N+logN*K)  空间复杂度:O(1)

3.当N非常大,远大于K。例如:1000亿个数里面找出最大的前10个。以上的方法就不能再使用。这里的1000亿个数就存放在磁盘中,也就是文件中。

那这时如何求解?

最优解:用前K个数建立一个K个数的小堆。然后剩下的N-K个一次遍历,如果比堆顶的数据大,就替换这个数进堆(向下调整)。

时间复杂度:O(K+logK*(N-K))  (N非常大,K很小,基本上就是O(N))

空间复杂度:O(K)

编程实现:

这里采用数组模拟,在随机处给出K个大于指定数的数,建立小堆。

Top—K问题测试示例:image.gif编辑

源码:

//Top-K问题
void PrintTopK(int* a, int n, int k) 
{
  // 1. 建堆--用a中前k个元素建堆
  int* kminHeap = (int*)malloc(sizeof(int) * k);
  assert(kminHeap);
  for (int i = 0; i < k; ++i)
  {
    kminHeap[i] = a[i];
  }
  //建小堆
  for (int j = (k - 1 - 1) / 2; j >= 0; --j)
  {
    AdjustDown(a, k, j);
  }
  // 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换
  for (int i = k; i < n; ++i)
  {
    if (a[i] > kminHeap[0])
    {
      kminHeap[0] = a[i];
      AdjustDown(kminHeap, k, 0);
    }
  }
  for (int j = 0; j< k; ++j)
  {
    printf("%d ", kminHeap[j]);
  }
  printf("\n");
  free(kminHeap);
}
//采用数组模拟
void TestTopk()
{
  int n = 10000;
  int* a = (int*)malloc(sizeof(int) * n);
  srand(time(0));
  for (size_t i = 0; i < n; ++i)
  {
    a[i] = rand() % 1000000;
  }
  //在随机处给出K个大于指定数的数
  a[5] = 1000000 + 1;
  a[1231] = 1000000 + 2;
  a[531] = 1000000 + 3;
  a[5121] = 1000000 + 4;
  a[115] = 1000000 + 5;
  a[2335] = 1000000 + 6;
  a[9999] = 1000000 + 7;
  a[76] = 1000000 + 8;
  a[423] = 1000000 + 9;
  a[3144] = 1000000 + 10;
  PrintTopK(a, n, 10);
}
int main()
{
  TestTopk();
  return 0;
}
image.gif

后记:

●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

                                                                          ——By 作者:新晓·故知

相关文章
|
1月前
|
机器学习/深度学习 算法 C语言
【趣学C语言和数据结构100例】11-15
本文介绍了五个C语言编程问题及其实现,包括矩阵对角线元素之和、有序数组插入、数组逆序、杨辉三角输出和魔方阵生成。每个问题不仅涉及基本的数组操作,还涵盖了算法设计的核心思想,如循环、条件判断和递归。通过解决这些问题,读者可以加深对C语言和数据结构的理解,提升编程技能。这些问题的解决过程展示了如何有效处理数组和矩阵,以及如何利用算法优化程序性能,为实际应用提供了宝贵的实践经验。
60 4
【趣学C语言和数据结构100例】11-15
|
28天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
45 1
|
1月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
49 4
|
1月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
45 4
|
1月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
45 4
|
1月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
52 4
|
1月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
43 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
36 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】51-55
本文介绍了五个关于链表操作的C语言实现案例,包括删除单链表中的重复元素、从两个有序链表中查找公共元素、判断一个链表是否为另一链表的连续子序列、判断循环双链表是否对称及合并两个循环单链表。每个案例都详细解析了算法思路与实现方法,涵盖了链表操作的多种场景,旨在帮助读者深入理解链表数据结构的应用,提升算法设计与编程能力。
43 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】16-20
本文精选了五个C语言编程问题,涵盖数组操作、字符串处理等基础领域。包括查找二维数组中的鞍点、折半查找法、统计文章中字符数量、电文解密及字符串连接。每个问题都附有详细的代码实现与分析,旨在帮助读者理解算法逻辑,提升编程技巧。通过这些实践,不仅能锻炼编程能力,还能加深对数据结构和算法的理解,为未来的学习和工作打下坚实基础。
66 4