本专栏持续输出数据结构题目集,欢迎订阅。
题目
请编写程序,将 n 个已经满足最小堆顺序约束的数据直接读入最小堆;随后将下一个读入的数据 x 插入堆;再执行删顶操作并输出删顶的元素;最后顺次输出堆中剩余元素以检验操作的正确性。
输入格式:
输入首先给出一个正整数 c(≤1000),为最小堆的最大容量;下一行给出正整数 n(<c);随后一行按层序遍历的顺序给出 n 个最小堆元素;最后一行给出将要插入堆的元素 x。所有堆元素均为 int 型范围内的整数。
输出格式:
在一行中输出插入后再删顶的元素,格式为 min = y,其中 y 为删顶元素值。
随后 n 行,按层序遍历的顺序每行输出一个最小堆元素。
输入样例:
10
6
1 5 3 7 9 8
2
输出样例:
min = 1
2
5
3
7
9
8
代码
#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000
int heap[MAXN + 1]; // 堆数组,下标从1开始
int size; // 当前堆的大小
// 交换两个元素
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 插入元素到最小堆
void insert(int x) {
heap[++size] = x; // 插入到末尾
int i = size;
// 向上调整
while (i > 1 && heap[i] < heap[i/2]) {
swap(&heap[i], &heap[i/2]);
i /= 2;
}
}
// 删除堆顶元素(最小值)
int deleteMin() {
int min = heap[1]; // 保存堆顶元素
heap[1] = heap[size--]; // 将最后一个元素移到堆顶
int i = 1;
// 向下调整
while (1) {
int left = 2 * i;
int right = 2 * i + 1;
int smallest = i;
// 找出当前节点及其子节点中的最小值
if (left <= size && heap[left] < heap[smallest])
smallest = left;
if (right <= size && heap[right] < heap[smallest])
smallest = right;
// 如果当前节点已经是最小值,停止调整
if (smallest == i) break;
swap(&heap[i], &heap[smallest]);
i = smallest;
}
return min;
}
int main() {
int c, n, x;
// 读取输入
scanf("%d", &c);
scanf("%d", &n);
size = n;
// 读入已有堆元素
for (int i = 1; i <= n; i++) {
scanf("%d", &heap[i]);
}
// 读取要插入的元素
scanf("%d", &x);
// 插入元素
insert(x);
// 删除堆顶元素并输出
int min = deleteMin();
printf("min = %d\n", min);
// 按层序遍历输出剩余元素
for (int i = 1; i <= size; i++) {
printf("%d\n", heap[i]);
}
return 0;
}
1537

被折叠的 条评论
为什么被折叠?



