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

湘潭网站制作建设seo外包服务项目

湘潭网站制作建设,seo外包服务项目,中低端网站建设客户网,个人做商业网站需要什么【数据结构】建堆算法复杂度分析及TOP-K问题 🔥个人主页:大白的编程日记 🔥专栏:数据结构 文章目录 【数据结构】建堆算法复杂度分析及TOP-K问题前言一.复杂度分析1.1向下建堆复杂度1.2向上建堆复杂度1.3堆排序复杂度 二.TOP-K问…

【数据结构】建堆算法复杂度分析及TOP-K问题

🔥个人主页大白的编程日记

🔥专栏数据结构


文章目录

  • 【数据结构】建堆算法复杂度分析及TOP-K问题
    • 前言
    • 一.复杂度分析
      • 1.1向下建堆复杂度
      • 1.2向上建堆复杂度
      • 1.3堆排序复杂度
    • 二.TOP-K问题
      • 2.1思路分析
      • 2.2代码实现
    • 后言

前言

哈喽,各位小伙伴大家好!上期我们讲了堆排序和建堆算法。今天我们就来分析一下他们的时间复杂度。话不多说,咱们进入正题。向大厂冲锋!

一.复杂度分析

我们都知道堆是一个完全二叉树。那他的高度h和节点数量N有什么关系呢?

那我们再来对比一下满二叉树和完全二叉树的高度h.

我们用大O渐进表示法看的话他们两个的高度h都可以认为是logN的量级
所以我们的堆的上下调整可以认为是logN,也就是高度次。

因为堆是完全二叉树,而满二叉树也是完全二叉树,所以为了方便证明
我们使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个结点不影响最终结果):

1.1向下建堆复杂度

我们先分别算出第一层到h-1层的节点个数和该层节点的调整次数
然后再推出总的调整次数。

  • 推导

1.2向上建堆复杂度

我们先分别算出第2层到h层的节点个数和该层节点的调整次数
然后再推出总的调整次数。

  • 推导

所以向下建堆的时间复杂度是O(N),向上建堆的复杂度是O(N*logN).
所以以后我们都尽量使用向下调整建堆。因为他的效率更高。

1.3堆排序复杂度

现在我们来看一下我们堆排序的时间复杂度是多少呢?

  • 推导

    堆排序的复杂度是O(N*logN).

二.TOP-K问题

2.1思路分析

我们的堆除了可以用来排序还可以用来解决经典的TOP-K问题。
TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

  • 方法一
    我们很容易想到直接排序然后取出前K个即可。
    但是这个方法有个致命缺陷。
    如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。

    我们发现这个方法在数据量太大的时候并不适用。
    那有什么其他好的方法吗?
  • 方法二
    最佳的方式就是用堆来解决,基本思路如下:
    1 .用数据集合中前K个元素来建堆
    前k个最大的元素,则建K个数的小堆
    前k个最小的元素,则建K个数的大堆
    2 . 用剩余的N-K个元素依次与堆顶元素来比较,
    如果比堆顶元素还要大或小(小堆大 大堆小)则替换堆顶元素,然后向下调整重新建堆。

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

为什么呢?

  • 证明

    我们通过N-K次比较就可以筛选出N-K个不满足最大前K个数的数
    剩下在堆的数就是最大的前K个。
  • 疑问

我们用反证法可以得知这种情况不存在。

2.2代码实现

  • 生成数据函数
    我们先用srand生成不同的种子防止生成的随机数是伪随机数。
    然后fopen打开文件。循环生成随机数然后写入文件即可。最后关闭文件。
void CreatData()
{int n = 100000;//生成10万个数据srand(time(0));//生成不同的种子FILE* pf = fopen("test.txt", "w");//打开文件for (int i = 0; i < n; i++){int x = rand() % 100001+i;//生成随机数fprintf(pf, "%d\n", x);//写数据}fclose(pf);//关闭文件pf = NULL;
}


这样10万个数据就生成好了。

  • 比较函数

我们先接收k。然后开好k个数是堆空间。
然后从文件读取前k个数并填充到堆里面。然后建堆
然后继续读取文件里的数据直到文件末尾(返回EOF)
然后当数据大于堆顶元素是在进堆,然后重新调整建堆即可。

void test()
{int k;printf("请输入前K个数:");scanf("%d", &k);int* a = (int*)malloc(sizeof(int) * k);//开空间建堆FILE* pf = fopen("test.txt", "r");for (int i = 0; i < k; i++){fscanf(pf, "%d", &a[i]);}//填充数据for (int i = (k - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, k, i);}//建小堆int x;while (fscanf(pf, "%d", &x) !=EOF){if (x > a[0]){a[0] = x;AdjustDown(a, k, 0);}}//对比for (int i = 0; i < k; i++){printf("%d ", a[i]);}//打印
}
  • 检验

那我们如何确保这10个数一定是最大的呢?万一我们的算法写错不是最大的前10个数怎么办?










那我们就可以在不同的地方在一些k标点。
也就是K个很大的数,确保他们是最大的前K个。
然后只需要看结果是不是这k个数即可。

大家发现结果就是我们手动给的这10个数。说明我们的程序时没问题的。

后言

这就是建堆算法复杂度分析及TOP-K问题。这里涉及到许多数学知识。大家可以多看几遍证明图。今天就分享到这里。感谢大佬们垂阅!咱们下期见!拜拜~

http://www.hkea.cn/news/224185/

相关文章:

  • 网站能不能自己做免费的seo教程
  • 湖南的商城网站建设优化教程网下载
  • 做网站需要哪些工程师西安seo诊断
  • tp做的网站封装成app2023北京封控了
  • 增城做网站要多少钱推广普通话手抄报
  • 石家庄网站系统开发智能搜索引擎
  • 迅速网站网络营销平台推广方案
  • 学前端要逛那些网站微信引流主动被加软件
  • 韩国flash网站免费手机网站建站平台
  • 东莞做网站卓诚网络昆明长尾词seo怎么优化
  • WordPress个性萌化插件郑州seo优化哪家好
  • 专业手机移动网站建设免费的seo优化
  • 西安网站建设王永杰域名注册 万网
  • 网站营销优化方案北京做的好的seo公司
  • 企业网站排名提升软件优化南宁seo优化
  • 创意合肥网站建设杭州seo公司排名
  • 网站专题页是什么中国十大关键词
  • 五月天做网站网络策划与营销
  • 高校网站如何建设论文谷歌官网下载
  • 做网站内容软件个人网站怎么做
  • 收废铁的做网站有优点吗海南百度推广开户
  • wordpress 二维码插件下载信阳搜索引擎优化
  • 个人网站二级域名做淘宝客企业推广策略
  • 厦门做网站seo的seo服务公司招聘
  • 安徽池州做企业网站百度搜索官方网站
  • 芜湖商城网站建设青岛百度快速优化排名
  • 我找伟宏篷布我做的事ko家的网站seoul怎么读
  • 即墨做网站优书网首页
  • 网站建设实践报告3000字放单平台
  • 中华人民共和国城乡住房建设厅网站seo技术外包