PAT甲级 堆 相关题_C++题解
堆
目录
- 《算法笔记》重点摘要
- 1147 Heaps (30)
- 1155 Heap Paths (30)
《算法笔记》 9.7 堆 重点摘要
1. 定义
堆是完全二叉树,树中每个结点的值不小于(或不大于)其左右子结点的值,称之为大顶堆(或小顶堆)
const int maxn = 100;
int heap[maxn], n = 10; // heap 为堆,n 为元素个数
2. 向下调整
// 对 heap 数组在 [low,high] 范围进行向下调整
// 其中 low 为欲调整结点的数组下标, high 一般为堆的最后一个元素的数组下标
void downAdjust(int low, int high){
int i = low, j = i * 2; // i 为欲调整结点,j 为其左子结点
while (j <= high){ // 存在子结点时进行循环
if (j + 1 <= high && heap[j+1] > heap[j) // 若右子结点存在且值大于左子结点
j = j + 1;
if (heap[j] > heap[i]){ // 若子结点中最大的值比欲调整结点 i 的值大
swap(heap[j], heap[i]);
i = j;
j = i * 2;
// 保持 i 为欲调整结点,j 为其左子结点
}
else break;
}
}
3. 建堆
- 完全二叉树叶子结点数为 ceil(n/2)
- 数组下标在 [1,floor(n/2)] 内均为非叶子节点
- 从 floor(n/2) 开始倒着枚举结点,对每个结点 i 进行 [i,n] 范围调整
- 保证每个节点都是以其为根结点的子树中值最大的结点
void createHeap(){
for (int i = n / 2; i >= 1; i--)
downAdjust(i,n);
}
4. 删除堆顶元素
用最后一个元素覆盖堆顶元素,再对根结点进行调整
void deleteTop(){
heap[1] == heap[n--]; // 覆盖后元素个数 --
downAdjust(1,n);
}
5. 向上调整
// 对 heap 数组在 [low,high] 范围进行向上调整
// 其中 low 一般设置为 1, high 为欲调整结点的数组下标
void upAdjust(int low, int high){
int i = high, j = i / 2; // i 为欲调整结点,j 为其父结点
while (j >= low){ // 父结点在 [low,high] 范围内
if (heap[j] < heap[i]){ // 父结点值小于欲调整结点值
swap(heap[j],heap[i]);
i = j;
j = i / 2;
// 保持i 为欲调整结点,j 为其父结点
}
else break;
}
}
6. 添加元素
void insert(int x){
heap[++n] = x;
upAdjust(1,n);
}
7. 堆排序
- 倒着遍历数组
- 访问到 i 位置时,将堆顶元素与 i 位置元素交换,则 i 位置固定为 [1,i] 最大值
- 在 [1,i-1] 范围对堆顶元素进行向下调整
void heapSort(){
createHeap();
for (int i = n; i > 1; i++){
swap(heap[i], heap[1]);
downAdjust(1, i-1);
}
}
8. 递推判断堆类型方法
bool isMax = true, isMin = true;
for (int i = 2; i <= n; i++) {
if (tree[i/2] > tree[i]) isMin = false;
if (tree[i/2] < tree[i]) isMax = false;
}
printf("%s\n", isMax ? "Max Heap" : isMin ? "Min Heap" : "Not Heap");
1147 Heaps (30)
题目思路
- 递推 判断堆类型,两个变量分别记录是否符合大顶堆 / 小顶堆
- 递归 保存后序遍历序列,按要求输出,注意每检查一个新的堆要将保存后序序列的容器清空
post.clear()
#include<iostream>
#include<vector>
using namespace std;
int n;
vector<int> tree, post;
void postorder(int index){
if (index > n) return;
postorder(index * 2);
postorder(index * 2 + 1);
post.push_back(tree[index]);
}
int main()
{
int m, data;
scanf("%d%d", &m, &n);
tree.resize(n+1);
for (int i = 0; i < m; i++){
for (int j = 1; j < n + 1; j++) scanf("%d", &tree[j]);
bool isMax = true, isMin = true;
for (int j = 2; j < n + 1; j++){
if (tree[j/2] > tree[j]) isMin = false;
if (tree[j/2] < tree[j]) isMax = false;
}
printf("%s\n", isMax ? "Max Heap" : isMin ? "Min Heap" : "Not Heap");
post.clear();
postorder(1);
for (int j = 0; j < post.size(); j++)
printf("%d%c", post[j], j + 1 == post.size() ? '\n' : ' ');
}
return 0;
}
1155 Heap Paths (30)
题目思路
- DFS 递归 输出路径
- 终止条件:到叶结点(
2 * index > n),输出路径 - 进入下一层条件:下一层的子结点存在
- 即递归确认下一个结点存在时才进入,能进入递归的都是存在非越界的结点,所以通过其子结点越界判断到叶结点,输出到此结点的路径
- 终止条件:到叶结点(
- 递归 判断是什么堆
- 每进入一个非根节点的结点,就判断它与父结点的大小关系
- 不符合大顶堆或小顶堆的就将对应变量置 false,符合要求的没有机会被置 false
- 最后根据变量输出判断结果
#include<iostream>
#include<vector>
using namespace std;
int n, tree[1001];;
bool isMax = true, isMin = true;
vector<int> path;
void DFS(int index){
if (index > 1){
if (tree[index] > tree[index/2]) isMax = false;
if (tree[index] < tree[index/2]) isMin = false;
}
if (2 * index > n){
for (int i = 0; i < path.size(); i++)
printf("%d%c", tree[path[i]], i == path.size()-1 ? '\n' : ' ');
return;
}
if (2 * index + 1 <= n){
path.push_back(2 * index + 1);
DFS(2 * index + 1);
path.pop_back();
}
path.push_back(2 * index);
DFS(2 * index);
path.pop_back();
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &tree[i+1]);
path.push_back(1);
DFS(1);
printf("%s\n", isMax ? "Max Heap" : isMin ? "Min Heap" : "Not Heap");
return 0;
}
PAT甲级 堆 相关题_C++题解的更多相关文章
- PAT甲级 Dijkstra 相关题_C++题解
Dijkstra PAT (Advanced Level) Practice Dijkstra 相关题 目录 <算法笔记>重点摘要 1003 Emergency (25) <算法笔记 ...
- PAT甲级 二叉树 相关题_C++题解
二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...
- PAT甲级 二叉查找树 相关题_C++题解
二叉查找树 PAT (Advanced Level) Practice 二叉查找树 相关题 目录 <算法笔记> 重点摘要 1099 Build A Binary Search Tree ( ...
- PAT甲级 图 相关题_C++题解
图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...
- PAT甲级 树 相关题_C++题解
树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...
- PAT甲级 散列题_C++题解
散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...
- PAT甲级 字符串处理题_C++题解
字符串处理题 目录 <算法笔记> 重点摘要 1001 A+B Format (20) 1005 Spell It Right (20) 1108 Finding Average (20) ...
- PAT甲级 并查集 相关题_C++题解
并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...
- PAT甲级 图的遍历 相关题_C++题解
图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...
随机推荐
- linux环境下完成jenkins的环境搭建
环境搭建部署: 请完成jenkins的环境搭建,需安装tomcat,mysql. Jenkins 地址: https://jenkins.io/download/ 步骤分析: 1.全部操作使用普通用 ...
- 【模板】分治FFT
蒟蒻写题解实在不易 前置 方法一:\(Cdq+NTT\) 方法二:多项式求逆 NTT总结:多项式求逆总结 方法一 \(Cdq+NTT\): \[f_i=\sum\limits_{j=1}^i f_{i ...
- Scrapy 教程(11)-API启动爬虫
scarpy 不仅提供了 scrapy crawl spider 命令来启动爬虫,还提供了一种利用 API 编写脚本 来启动爬虫的方法. scrapy 基于 twisted 异步网络库构建的,因此需要 ...
- python3编程基础之一:标识符
每种编程语言都是需要处理数据的,需要变量.函数.类等,而这些都是通过名称访问的.因此,能够作为变量.函数.类等名称的字符串就是标识符.数据,是计算机进行运算的实体.标识符,用来标记的符号,它会指向一个 ...
- DNN在推荐系统中的应用参考资料
参考资料 DSSM算法计算文本相似度:https://www.cnblogs.com/wmx24/p/10157154.html Deep Neural Network for YouTube Rec ...
- macbook配置flutter环境变量
打开命令窗口,如果没有文件的,可以手动创建文件 code ~/.bash_profile 打开的文件内容如下,如果新增的空文件,肯定是空白的 如果将flutter存放到了应用中,可以如下操作,如果不是 ...
- [Java]在JAVA中使用Oracle的INSERT ALL语法进行批量插入
Oracle也提供了类似MySQL的批量插入语法,只是稍微别扭些,具体代码如下: package com.hy; import java.sql.Connection; import java.sql ...
- vue---vue2.x自定义plugin,给vue添加全局方法,原型上增加全局方法
1. 自定义plugin.js export default{ install(Vue,options); { Vue.prototype.toStringTwo=(str)=>( ('0000 ...
- Android简单实现滚动悬停效果
import android.content.Context; import android.support.design.widget.TabLayout; import android.suppo ...
- 使用libxml2创建和解析xml文件
毕业设计需要用到xml文件来组织和存放数据, 对于Linux环境下,有libxml2可供使用. 经过一段时间查询文档和网站, 基本掌握创建xml文档和解析xml的操作, 简单做一下记录. 创建xml ...