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

桂林旅游网站建设百度浏览器手机版

桂林旅游网站建设,百度浏览器手机版,梵克雅宝四叶草手链,黄岩区住房保障建设局网站目录 1.建堆(以大堆为例) 1.1向上调整法建大堆 1.2向下调整法建大堆 1.3建堆方法的时间复杂度 2.堆排序(以升序为例) 3.TOP-K问题 筛选前K大 1.建堆(以大堆为例) 给定一个数组,在此基础上进行建大堆操作 1.1向上调整法建大堆 模拟堆插入数据的操作&#xff0c…

目录

1.建堆(以大堆为例)

1.1向上调整法建大堆

1.2向下调整法建大堆 

 1.3建堆方法的时间复杂度

2.堆排序(以升序为例)

3.TOP-K问题

筛选前K大


1.建堆(以大堆为例)

给定一个数组,在此基础上进行建大堆操作

1.1向上调整法建大堆

模拟堆插入数据的操作,从数组的第二个元素开始进行向上调整操作,直到最后一个元素调整结束为止,最终可实现大堆

原理:每一次向上调整(算法正确的前提下)都会将所给数据构成的树实现为大堆

 

void AdjustUp(HpDateType* a, int child)
{//给定数组为空时,没必要进行下面步骤assert(a);int parent = (child - 1) / 2;//parent恒大于等于0while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}//向上调整法建大堆,模拟插入的过程  O(N*logN)
for (int i = 1; i < n; ++i)
{AdjustUp(a, i);
}

1.2向下调整法建大堆 

思路:从倒数第一个非叶子结点开始进行向下调整操作,直到根节点为止,最终可实现大堆

原理:每一次向下调整(算法正确的前提下)都会将以该节点为根节点的树调整为大堆

 

void AdjustDown(HpDateType* a, int n, int parent)
{int child = parent * 2 + 1;//有左孩子才进行调整while (child < n)//n是节点个数{//左孩子一个逻辑,右孩子一个逻辑,直接假设//child是左右孩子中较大的一个孩子的下标//注意右孩子的有无(防止越界访问与无效数据)if (child + 1 < n && a[child] < a[child + 1]){++child;}//与左右孩子中较大的一个孩子进行比较if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}//向下调整法建大堆  O(N)
for (int i = (n - 1 - 1) / 2; i >= 0; --i)
{AdjustDown(a, n, i);
}

 1.3建堆方法的时间复杂度

调整法建堆,时间复杂度是O(N*logN)

调整法建堆,时间复杂度是O(N)

显然, 向调整法建堆 优于 向调整法建堆

记忆方法:向下建堆时,节点数越多的所在层的节点调整次数越少,节点数越少的所在层的节点调整次数越多;向上建堆时,节点数越多的所在层的节点调整次数越多,节点数越少的所在层的节点调整次数越少

可通过计算最坏情况下树高为h的满二叉树的调整次数得出相应时间复杂度的结论(需结合树高与节点数的关系以及错位相减法的知识点)

亦可通过估算最坏情况下底层节点数据的调整次数得出相应时间复杂度的结论,因为底层数据几乎占所有数据的一半

2.堆排序(以升序为例)

排升序,建大堆;排降序,建小堆

思路:先将所给数组进行建堆操作,再将堆顶元素与末尾元素进行交换,然后在除了末尾元素之外的数据基础上进行向下调整操作,使得次大元素位于堆顶,然后再将次大元素与倒数第二个元素进行交换........如此循环,直到堆顶元素与数组第二个元素进行交换后为止,最终可实现升序

void HeapSort(int* a, int n)
{//向下调整法建大堆  O(N)for (int i = (n - 1 - 1) / 2; i >= 0; --i){AdjustDown(a, n, i);}//排升序,建大堆  O(N*logN)int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

堆排序的原理:通过逐步缩小堆的范围来排序数组,当堆中只剩一个元素时(即 end = 0),排序过程已完成

 所以 end > 0 作为循环结束条件

3.TOP-K问题

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

 求前K个最大的数据的思路

(1)构建一个大小为K的小根堆,初始时存入数组前K个元素,并调整为堆结构。此时堆顶是堆内K个元素的最小值,作为全局前K大的“门槛”

(2)遍历剩余数据:若当前元素 大于堆顶,说明它可能属于前K大,于是替换堆顶,并执行向下调整操作;若当前元素 小于等于堆顶,则跳过(因为它不可能属于前K大)。

最终堆中保留的即为全局前K大的元素

原理:

(1)小堆的堆顶始终是当前候选集中的最小值,插入的较大元素会通过堆调整找到正确位置(不一定是叶子节点),而堆顶始终更新为新的最小值,从而保证堆内元素的正确性

 不用大堆是因为如果所有数据中的最大值位于大堆堆顶,那么就无法通过有效的比较逻辑筛选出余下的较大值

 求前K个最小的数据的思路

(1)构建一个大小为K的大根堆,初始时存入数组前K个元素,并调整为堆结构。此时堆顶是堆内K个元素的最大值,作为全局前K小的“门槛”

(2)遍历剩余数据:若当前元素 小于堆顶,说明它可能属于前K小,于是替换堆顶,并执行向下调整操作;若当前元素 大于等于堆顶,则跳过(因为它不可能属于前K小)。

最终堆中保留的即为全局前K小的元素

原理:

(1)大堆的堆顶始终是当前候选集中的最大值,插入的较小元素会通过堆调整找到正确位置(不一定是叶子节点),而堆顶始终更新为新的最大值,从而保证堆内元素的正确性

 

 不用小堆是因为如果所有数据中的最小值位于大堆堆顶,那么就无法通过有效的比较逻辑筛选出余下的较小值

筛选前K大

void PrintTopK(const char* file, int k)
{FILE* fp = fopen(file, "r");if (fp == NULL){perror("fopen fail");return;}//存储前k个int* a = (int*)malloc(sizeof(int) * k);if (a == NULL){perror("malloc fail");return;}for (int i = 0; i < k; ++i){fscanf(fp, "%d", &a[i]);}//建小堆for (int i = (k - 2) / 2; i >= 0; --i){AdjustDown(a, k, i);}//读取后续并比较int val = 0;int ret = fscanf(fp, "%d", &val);while (ret != EOF){if (val > a[0]){Swap(&val, &a[0]);AdjustDown(a, k, 0);}ret = fscanf(fp, "%d", &val);}for (int i = 0; i < k; ++i){printf("%d ", a[i]);}fclose(fp);fp = NULL;free(a);a = NULL;
}

http://www.dtcms.com/wzjs/448650.html

相关文章:

  • 安平做网站的公司提交百度一下
  • 企业网站建设意义南昌seo推广
  • 软件测试7种方法百度seo排名优化价格
  • wordpress多站点插件惠州seo建站
  • 我们是设计师 网站建设专家西安最新消息今天
  • 潍坊建网站的seo站长工具下载
  • 网站开发实训心得体会服务外包公司
  • 山东广饶县建设局网站今天实时热搜榜排名
  • 基于dreamweaver设计网页的步骤北京百度seo关键词优化
  • 海口日报社官网宁波网站推广优化公司电话
  • 安徽两学一做网站成都百度搜索排名优化
  • ipv6网站制作软件公司
  • 设计站深圳网站设计制作
  • 广州网站建设联雅长沙seo
  • 网站建设自学 优帮云网站提交入口
  • 网站制作中搜索栏怎么做seo优化博客
  • 移动云服务器租用爱采购seo
  • 怎样做免费网站卖东西关键词com
  • 一个空间可以做两个网站吗百度指数怎么看
  • 旅游兼职网站建设google浏览器官网下载
  • 多多搜索推广seo观察网
  • 上海网站改版方案网络营销模式下品牌推广途径
  • 青岛网站建设推广服务长春网站建设公司
  • 北京市委网站百度下载免费安装到桌面
  • wordpress制作页面模板兰州网络seo公司
  • 怎么用ftpxp做网站昆明seocn整站优化
  • 12306网站建设费用网络推广文案
  • 指定网站怎么设置路由器只访问新产品推广方案范文
  • 合适的网站制作需要多少钱网站域名查询
  • 网站建设公司织梦模板下载榜单优化