数据结构——堆PTA习题

简介: 数据结构——堆PTA习题

单选题


image.png


选择题题解


1、完全二叉树(深度为 k ,有 n 个结点的二叉树当且仅当其每一个结点都与深度为 k 的满二叉树中编号从 1 至 n 的结点一一对应时,称为完全二叉树。)



满二叉树(堆不保证节点的个数正好能构成满二叉树)


二叉排序树(最小堆只保证父节点比孩子节点小,并不是二叉排序树)


平衡二叉树(二叉平衡树肯定是一颗二叉排序树,堆不是二叉排序树)


3、(5,8,12,19,28,20,15,22)



插入3,3换19再换8再换5


10、是建树后调整序列的规则,是从第【n/2】(个节点最后一个有儿子的节点)向前面的【n/2-1】等节点的顺序进行,可以看作是自底向上、同层自右向左的顺序进行,找同级最大的一层层向上移动。



编程题


堆中的路径 — 用数组建立堆


这个题比较简单,就是用数组建立一个堆,这个堆也是个完全二叉树,所以满足性质:

从1开始的数组中父结点的下标是子结点下标的 int ( i / 2 )


主要操作:


代码中最主要的步骤就是在堆中插入一个元素:


为了满足完全二叉树,我们需要把新的结点先放到最后一个位置,


为了满足最小堆的建立,我们把新的结点进行与父结点比较并调整


我们在与父结点比较时,因为数组的有效结点是从1开始的,我们应该避免与数组的0元素比较


我们可以在0这个下标放一个特别特别小的数


使得在Insert这个操作中,我们不需要单独设置一个条件避免与H[0]比较


而是直接不让H[0]满足H[i / 2] > X这个条件


代码


#include<stdio.h>
#include<stdlib.h>
int H[1001], size;
// 构建最小堆
void Insert(int x)
{
  // 先放到最后一个位置(为了满足二叉树要求),之后再调整其位置(为了满足堆要求)
  int i;
  for (i=++size;H[i/2]>x ;i/=2)
  {
    H[i] = H[i / 2];  // 当父结点比x大时,把x放在父结点位置上   父结点的下到子结点
  }
  H[i] = x;
}
int main()
{
  int n, m, x, i, j;
  scanf("%d %d", &n, &m);
  size = 0;
  H[0] = -10001;  // 设置岗哨,使得每次遍历树的父结点的结束条件变得简单
  for (i = 0; i < n; i++)
  {
    scanf("%d", &x);
    Insert(x);
  }
  for (i = 0; i < m; i++)
  {
    scanf("%d", &j);
    printf("%d", H[j]);
    while (j>1)
    {
      j /= 2;
      printf(" %d", H[j]);
    }
    printf("\n");
  }
  return 0;
}


7-1 关于堆的判断 (25分)


将一系列给定数字顺序插入一个初始为空的小顶堆H[]。随后判断一系列相关命题是否为真。命题分下列几种:


x is the root:x是根结点;


x and y are siblings:x和y是兄弟结点;


x is the parent of y:x是y的父结点;


x is a child of y:x是y的一个子结点。


输入格式:


每组测试第1行包含2个正整数N(≤ 1000)和M(≤ 20),分别是插入元素的个数、以及需要判断的命题数。下一行给出区间[−10000,10000]内的N个要被插入一个初始为空的小顶堆的整数。之后M行,每行给出一个命题。题目保证命题中的结点键值都是存在的。


输出格式:


对输入的每个命题,如果其为真,则在一行中输出T,否则输出F。


输入样例:


5 4
46 23 26 24 10
24 is the root
26 and 23 are siblings
46 is the parent of 23
23 is a child of 10


输出样例:


F
T
F
T


代码


#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstdlib>
#define INF 1000000
using namespace std;
int a[1010], n, m;  // a存堆
// 插入小顶堆
/*
  调整序列的规则 : 是从第【n/2】(个节点最后一个有儿子的节点)向前面的【n/2-1】等节点的顺序进行
*/
int insert(int i) 
{
  int temp;
  while (a[i / 2] > a[i] && i != 1) 
  {
    temp = a[i];
    a[i] = a[i / 2];
    a[i / 2] = temp;
    i = i / 2;  
  }
  return 0;
}
// 找元素的爸爸
int find(int x) 
{
  int p, i;
  for (i = 1; i <= n; i++)
  {
    if (a[i] == x)
      p = i;
  }
  return a[p / 2];
}
// 判断函数
int panduan() 
{
  string str, str1, str2;
  int x, y;
  char ch;
  cin >> x >> str;
  if (str == "and") 
  {
    cin >> y >> str1 >> str2;
    if (find(x) == find(y))   // 兄弟结点就找相同的爸爸就行
      cout << "T" << endl;
    else
      cout << "F" << endl;
    return 0;
  }
  cin >> str;
  if (str == "a") {
    cin >> str1 >> str2 >> y;
    if (find(x) == y)     // x是y的一个子结点。 看x的爸爸是不是y
      cout << "T" << endl;
    else
      cout << "F" << endl;
    return 0;
  }
  cin >> str;
  if (str == "root") {      // x是根结点;   看x是不是第一个
    if (a[1] == x)
      cout << "T" << endl;
    else
      cout << "F" << endl;
    return 0;
  }
  cin >> str1 >> y;
  if (find(y) == x)       // x是y的父结点; 看y的爸爸是不是x
    cout << "T" << endl;
  else
    cout << "F" << endl;
  return 0;
}
int main() 
{
  cin >> n >> m;
  int i, j;
  cin >> a[1];
  for (i = 2; i <= n; i++) 
  {
    cin >> a[i];
    insert(i);//除了第一个节点不用进行插入排序,余下节点都需要进行插入排序
  }
  while (m--) 
  {
    panduan();//对字符串进行对错判断
  }
  return 0;
}
相关文章
|
28天前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
34 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
1月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
66 16
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
2月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
2月前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
78 1
|
3月前
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
60 5
【数据结构】优先级队列(堆)从实现到应用详解
|
2月前
|
存储 算法 调度
数据结构--二叉树的顺序实现(堆实现)
数据结构--二叉树的顺序实现(堆实现)
|
2月前
|
存储 算法 分布式数据库
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
|
2月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
2月前
|
存储 算法 Java
【用Java学习数据结构系列】用堆实现优先级队列
【用Java学习数据结构系列】用堆实现优先级队列
34 0