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

网站建设思想重视不够日照网络推广公司

网站建设思想重视不够,日照网络推广公司,房县网站建设,创作平台堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。大堆:每个节点的值都大于或者等于他的左右孩子节点的值小堆:每个结点的值都小于或等于其左孩子和右孩子结点…

堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。

大堆:每个节点的值都大于或者等于他的左右孩子节点的值

小堆:每个结点的值都小于或等于其左孩子和右孩子结点的值

不管是大堆还是小堆父节点的数组下标和其孩子节点的下标关系都为

parent=(child-1)/2 leftchild=2*parent+1 rightchild=2*parent+2

  1. 建堆

建堆有两种方法1.向上调整建堆2.向下调整建堆

  1. 向上调整建堆

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void AdjustUp(int* a, int child)     //向上调整
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent])    //建大堆还是小堆在这里调整{                            //大堆a[parent]<a[child] 小堆反之Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HeapSort(int* a, int n)
{for (int i = 0; i < n; ++i){AdjustUp(a, i);}
}int main()
{int a[] = { 1,10,2,20,3,30,4,40,5,50 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); ++i){printf("%d ", a[i]);}return 0;
}

向上调整建堆是从数组的第一个元素开始一次向后遍历数组元素,每一个数组元素都向上调整建堆,这个过程就模拟建立起了堆,这个过程的时间复杂度推导过程:O(N*logN)

2.向下调整建堆(推荐使用)

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void AdjustDown(int* a, int n, int parent)     //向下调整
{int minChild = parent * 2 + 1;while (minChild < n){if (minChild + 1 < n && a[minChild + 1] > a[minChild])   //这里控制大小堆{minChild++;}if (a[minChild] > a[parent]) //这里控制大小堆{Swap(&a[minChild], &a[parent]);parent = minChild;minChild = parent * 2 + 1;}else{break;}}}
void HeapSort(int* a, int n)
{for (int i = (n - 1-1) / 2; i >= 0; --i){AdjustDown(a, n, i);}
}int main()
{int a[] = { 1,10,2,20,3,30,4,40,5,50 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); ++i){printf("%d ", a[i]);}return 0;
}

向下调整的开始的位置是最后一个元素的父节点位置,因为最后一行的元素本来就符合大堆或者小堆的性质所以不用调整,根据数组的最后一个元素的下标计算出该节点的父节点的数组下标,从这个父节点开始向下调整,调整完后再将父节点的数组下标--,再从这个节点开始向下调整,直到调整完根节点后调整结束,堆就建立好了,大小堆是根据向下调整函数里的比较决定的。时间复杂度推导如下O(N):

因为向下调整的时间复杂度低于向上调整的时间复杂度,所以推荐使用的是向下调整建堆。

2.选数

了解完以后,我们来实现堆排序:

void AdjustDown(HPDataType* a, int n, int parent)
{//最小的默认为左孩子int minchild = 2 * parent + 1;while (minchild <n){//找出小的那个孩子if (minchild+1<n&&a[minchild+1] < a[minchild]){minchild++;}//小堆if (a[minchild] < a[parent]){Swap(&a[minchild], &a[parent]);parent = minchild;minchild = 2 * parent + 1;}else{break;}}
}void HeapSort(int* a, int n)
{for (int i = (n-1-1)/2; i>=0; i--){AdjustDown(a, n, i);}//选数int i = 1;while (i < n){Swap(&a[0], &a[n - i]);AdjustDown(a, n - i, 0);i++;}}int main()
{int a[] = { 15,1,19,25,8,34,65,4,27,7 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++){printf("%d ", a[i]);}printf("\n");return 0;
}

这里的思路就是先对数组进行向下调整建堆,如果要升序就建立大堆,将根节点位置的元素和最后一个元素交换位置使得最大的元素放到了数组的最后边,放到后边的元素不参与向下调整(通过传参控制),然后让被换到根节点的元素向下调整,回到符合堆的性质的位置,此时调整完成后次大的元素被调整到了根节点的位置,再让根节点的元素和倒数第二个元素交换,交换到后边的元素不参与向下调整,再次进行向下调整,直到i=n时结束调整,此时输出数组就是升序的。如果要降序那就建立小堆。

总结一句话:

升序--建大堆,降序--建小堆

3.TOP-K问题

如何从数组中找到前K个大或者前K个小的数?

错误的思维:

选前K个大的数建立的是大堆,那最大的元素就在最上方,我们拿走了最大的元素,那剩下的元素堆的关系全乱了,又得重新排序,再选出最大的元素,这样一来假设要从特别大的一堆数据中进行选数那代价就非常大了,效率变得很低。同理选小数不能建小堆。

正确方法

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

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

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

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

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

代码实现:

#include<stdlib.h>
#include<stdio.h>void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}void AdjustDown(int* a, int n, int parent)     //向下调整
{int minChild = parent * 2 + 1;while (minChild < n){if (minChild + 1 < n && a[minChild + 1] < a[minChild]){minChild++;}if (a[minChild] < a[parent]){Swap(&a[minChild], &a[parent]);parent = minChild;minChild = parent * 2 + 1;}else{break;}}}
void Topk(int* a, int k,int n)
{int* minheap = (int*)malloc(k * sizeof(int));if (minheap == NULL){perror("malloc fail!");exit(-1);}for (int i = 0; i < k; i++){minheap[i] = a[i];}for (int j = (k - 2) / 2; j >= 0; --j){AdjustDown(minheap, k, j);   //向下调整建小堆因为选的是前K大的数 ---如果选小数就建大堆}int k1 = k;//遍历k后的元素交换然后调整while (k <n){if (a[k] > minheap[0]){minheap[0] = a[k];AdjustDown(minheap, k, 0);}++k;}for (int i = 0; i < k1; ++i){printf("%d ", minheap[i]);}}
int main()
{int a[] = { 1,10,2,20,3,30,4,40,5,50 };int k = 5;  //选出前5个大的数int n = sizeof(a) / sizeof(int);  //数组元素个数Topk(a, k,n);return 0;
}

http://www.15wanjia.com/news/31979.html

相关文章:

  • 网站建设微信版今日腾讯新闻最新消息
  • 昆明网站建设搜q.479185700windows优化大师有必要安装吗
  • 哪家网站建设培训心得总结
  • 类似优酷的网站开发电脑优化系统的软件哪个好
  • 找公司做网站多少钱深圳seo公司助力网络营销飞跃
  • asp网站qq登录建站 seo课程
  • 泰安赶集网什么叫优化关键词
  • 如何将自己做的网站变成中文免费私人网站建设
  • wordpress插件问题关键词优化推广排名多少钱
  • 国外网站可以访问吗百度推广哪家做的最好
  • 设计软件免费版seo发外链的网站
  • 急招钟点工4小时220元引擎seo优
  • 全球新冠疫苗接种率成都网站seo报价
  • 如何设置网站名字吗千锋教育和达内哪个好
  • 成都高级网站建设合肥网站设计
  • 深圳网站建设迅美深圳seo外包公司
  • html5 网站正在建设中百度seo不正当竞争秒收
  • java做的网站源码seo外包 靠谱
  • 免费网站空间怎么做上海优化外包公司排名
  • 学做视频的网站有哪些内容seo服务
  • 怎么做不用数据库的网站阿里云域名购买
  • 各大搜索引擎网站提交入口成都最好的网站推广优化公司
  • wordpress无法拖动小工具栏网站优化方案
  • 西宁网站建设平台公司seo互联网营销培训
  • 最早做网站的那批人国内新闻最新消息
  • 最专业的企业营销型网站建设站长工具ip地址
  • 怎么用大淘客做网站软文发布软件
  • 好的网站域名长沙网站seo诊断
  • 网站建设培训哪里好专业关键词排名优化软件
  • 南通公司建站模板营业推广是什么