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

短链接生成器手机版网站优化网站优化

短链接生成器手机版,网站优化网站优化,wordpress网站布局,分类网站建设一、堆的定义 堆是一棵完全二叉树,树中的每个结点的值都不小于(或不大于)其左右孩子结点的值。其中,如果父亲结点的值始终大于或等于孩子结点的值,那么称这样的堆为大顶堆,这时每个结点的值都是以它为根节…

一、堆的定义

堆是一棵完全二叉树,树中的每个结点的值都不小于(或不大于)其左右孩子结点的值。其中,如果父亲结点的值始终大于或等于孩子结点的值,那么称这样的堆为大顶堆,这时每个结点的值都是以它为根节点的子树的最大值;如果父节点的值始终小于或等于孩子结点的值,那么称这样的堆为小顶堆,这时每个结点的值都是以它为根节点的子树的最小值。

PS:下列所有操作针对大顶堆进行实现,如果构造小顶堆,利用相反思路即可,这里不做阐述。

二、堆的构造

那么给定一个初始序列怎么把它构造成堆呢?这里我们以构造大顶堆为例,进行演示。

假如给定一个整数序列为88、55、82、57、68、92、99、98、66、56

将他们按照树的层序从上到下、从左往右依次摆放,就得到了我们的初始堆。

 

从第一个非叶子结点开始,自右往左、自下往上,进行堆的调整,直至根节点为止。

对于每次访问的结点x,将结点x和它的下一级结点权值(左子树和右子树)进行比较,如果存在下一级结点的权值比结点x的大,将结点x与下一级结点中权值最大的进行交换。交换完后让结点x继续与下一级的结点进行比较,直到不存在下一级结点或者下一级结点权值都比结点x小为止。  

三、堆的代码实现

我们知道堆其实是一棵完全二叉树,那么我们也很容易可以知道,在完全二叉树中,对于结点x,它的左子树是结点2*x,右子树是2*x+1。根据这个性质,我们只需要用一个数组就可以对堆进行构造,定义堆数组如下:

int n;             //堆中结点数 
int heap[10010];   //定义堆数组

 我们先根据给定初始序列建立初始堆

cin>>n;
for(int i=1;i<=n;i++) cin>>heap[i];

 接着我们要找到这个完全二叉树的第一个非叶子结点,其实就是最后一个结点n的父节点,所以第一个非叶子节点下标即为n/2。然后我们从这个结点开始往前进行遍历,直至遍历到根结点1为止。

在进行一次遍历时,对该节点进行堆的调整(向下调整),具体代码实现如下:

//调整 
void downAdjust(int low,int high){int i=low,j=i*2;   //i为需要被调整的结点,j为i的左孩子结点 while(j<=high){     //如果存在孩子结点,继续进行调整if(j+1<=high&&heap[j+1]>heap[j]){j=j+1;  //如果右子树存在,且右子树的权值大于左子树,更新j为权值最大的子树的下标 } if(heap[j]>heap[i])      //如果存在孩子结点的最大权值大于父节点,进行调整 {swap(heap[j],heap[i]);  i=j;j=i*2;     //更新调整结点的为止,和调整结点的新的子结点 }else break; }
} //堆的构建,对初始堆进行调整 
void createHeap(int n){for(int i=n/2;i>=1;i--)downAdjust(i,n);     //对结点i进行向下调整 
}

 完整代码实现如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'int n;             //堆中结点数 
int heap[10010];   //定义堆数组//调整 
void downAdjust(int low,int high){int i=low,j=i*2;   //i为需要被调整的结点,j为i的左孩子结点 while(j<=high){     //如果存在孩子结点,继续进行调整if(j+1<=high&&heap[j+1]>heap[j]){j=j+1;  //如果右子树存在,且右子树的权值大于左子树,更新j为权值最大的子树的下标 } if(heap[j]>heap[i])      //如果存在孩子结点的最大权值大于父节点,进行调整 {swap(heap[j],heap[i]);  i=j;j=i*2;     //更新调整结点的为止,和调整结点的新的子结点 }else break; }
} //堆的构建,对初始堆进行调整 
void createHeap(int n){for(int i=n/2;i>=1;i--)downAdjust(i,n);     //对结点i进行向下调整 
}signed main(){cin>>n;for(int i=1;i<=n;i++) cin>>heap[i];createHeap(n);for(int i=1;i<=n;i++) cout<<heap[i]<<' '; } 

四、堆的结点增加和删除

我们都知道,在适用STL中的priority_queue构建堆的时候,可以进行结点的增加和删除,并且在增加结点和删除结点操作后,依旧保持大顶堆和小顶堆。那么在实际实现中,怎么实现上述操作呢?

1、堆的结点增加

在堆中,如果要进行结点的增加操作,一般我们将结点增加到数组的末尾,得到数据data,令heap[++n]=data。然后再向上进行调整。这里需要注意的是,在堆中增加结点时,需要向上进行结点的调整,对于新增加的结点x,将x与它的父节点进行比较,如果结点x的权值大于它的父结点 结点x/2,那么就交换两个结点,并将x的位置进行更新为x/2。然后继续向上机械能比较,如果调整到了根节点(即x/2==0)或者结点x的权值不大于父亲结点了。说明调整结束,结点增加成功。代码实现如下:

//从high向上调整 
void upAdjust(int low,int high){int i=high,j=i/2;while(j>=low){if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=i/2;}else break;}
}void insert(int x){heap[++n]=x;upAdjust(1,n); }

 2、堆的结点删除(删除堆顶元素)

一般进行堆的结点删除指的是删除堆顶元素,这个实现思路非常简单,就是将堆顶元素用heap[n]进行覆盖,再n--,然后再将堆顶元素向下调整。

void deleteTop(){heap[1]=heap[n--];downAdjust(1,n);
}

 3、完整代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'int n;             //堆中结点数 
int heap[10010];   //定义堆数组//调整 
void downAdjust(int low,int high){int i=low,j=i*2;   //i为需要被调整的结点,j为i的左孩子结点 while(j<=high){     //如果存在孩子结点,继续进行调整if(j+1<=high&&heap[j+1]>heap[j]){j=j+1;  //如果右子树存在,且右子树的权值大于左子树,更新j为权值最大的子树的下标 } if(heap[j]>heap[i])      //如果存在孩子结点的最大权值大于父节点,进行调整 {swap(heap[j],heap[i]);  i=j;j=i*2;     //更新调整结点的为止,和调整结点的新的子结点 }else break; }
} //堆的构建,对初始堆进行调整 
void createHeap(int n){for(int i=n/2;i>=1;i--)downAdjust(i,n);     //对结点i进行向下调整 
}//从high向上调整 
void upAdjust(int low,int high){int i=high,j=i/2;while(j>=low){if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=i/2;}else break;}
}void insert(int x){heap[++n]=x;upAdjust(1,n); }
void deleteTop(){heap[1]=heap[n--];downAdjust(1,n);
}
signed main(){cin>>n;for(int i=1;i<=n;i++) cin>>heap[i];createHeap(n);for(int i=1;i<=n;i++) cout<<heap[i]<<' '; int x;cin>>x;insert(x);for(int i=1;i<=n;i++) cout<<heap[i]<<' '; cout<<endl;deleteTop();for(int i=1;i<=n;i++) cout<<heap[i]<<' '; } /*
10
88 55 82 57 68 92 99 98 66 56
*/

五、堆排序

堆排序是指使用堆结构对一个序列进行排序。此处讨论递增排序的情况。

堆排序的思路其实就是删除堆顶元素的思路,我们可以知道,删除堆顶元素进行调整后,可以得到新的大顶堆堆顶,如果一直进行删除堆顶元素操作,得到的大顶堆堆顶序列,是不是就是我们的堆排序序列呢。(对于堆排序可以用STL priority实现,时间复杂度为O(nlogn) )。

void heapSort(int n){for(int i=n;i>1;i--){  swap(heap[1],heap[i]);downAdjust(1,i-1); } 
}

 假设堆里已经有元素。

priority_queue<int> heap;
void heapSort(){cout<<heap.top()<<' ';heap.pop();
}

 六、例题

L2-012 关于堆的判断 - 团体程序设计天梯赛-练习集

 

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

相关文章:

  • 怎么在日本做乐天网站供货商外汇seo公司
  • 网站建设在开封找谁做365优化大师软件下载
  • 建设局网站新闻在百度上怎么发布信息
  • 网站做缓存个人网站制作
  • 响应式网站设计软件中国四大软件外包公司
  • 济南网站建设山东聚搜网推荐陕西网站建设网络公司
  • 有机玻璃东莞网站建设技术支持灰色行业怎么推广引流
  • 做网站推广有用吗品牌整合推广
  • 哪个不是网站开发工具搭建一个网站的流程
  • 企业管理顾问咨询孝感seo
  • 马云有没有学过做网站seo建站技巧
  • 做饰品一般用什么网站做首饰网站外链发布平台
  • html5网站优点谷歌商店下载不了软件
  • 什么网站有做面条的appks数据分析神器
  • 网站设计语言翻译今日新闻最新消息
  • 电商网站建设计划书宁波 seo排名公司
  • 怎么做网站dreamwave南宁优化推广服务
  • 免抵退税在哪个网站做宁波百度关键词推广
  • 易网做的网站后台torrentkitty磁力猫
  • 一般做自己的网站需要什么竞价推广托管公司介绍
  • 机票特价网站建设怎么给公司做网站
  • 做自己的网站收费吗百度竞价推广登录
  • 国外活动策划网站深圳谷歌seo公司
  • b2b网站建设排名营销公司
  • 设计网站的步骤有哪些广告优化师培训
  • 祁阳网站设计重庆seo网络优化咨询热线
  • 安徽网站建站系统平台推广衣服的软文
  • 如何让百度收录自己的网站天津百度推广公司电话
  • 贵州住房和城乡建设网站bim友情链接交换工具
  • wordpress图片主题中文版seo排名点击软件