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

【PTA数据结构 | C语言版】哈夫曼树的实现

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

    • 题目
    • 代码

题目

请根据给定的 n 个权重,建立哈夫曼树,并计算带权路径长度 WPL。

输入格式:
每组测试第 1 行包含正整数 n (2<n≤10^4),为权重的个数。随后一行中给出 n 个不超过 10^4 的正整数权重,数字间以空格分隔。

输出格式:
在一行中输出根据给定的 n 个权重建立的哈夫曼树所对应的带权路径长度 WPL。

输入样例:
5
3 2 5 1 4

输出样例:
33

代码

#include <stdio.h>
#include <stdlib.h>#define MAXN 10001
#define INF 0x7FFFFFFFtypedef struct {int *data;  // 存储元素的数组int size;   // 当前堆的大小int capacity; // 堆的最大容量
} MinHeap;// 创建最小堆
MinHeap* CreateHeap(int capacity) {MinHeap* heap = (MinHeap*)malloc(sizeof(MinHeap));heap->data = (int*)malloc((capacity + 1) * sizeof(int));heap->size = 0;heap->capacity = capacity;heap->data[0] = -INF;  // 哨兵,小于所有可能的元素值return heap;
}// 插入元素到最小堆
void Insert(MinHeap* heap, int x) {int i;for (i = ++heap->size; heap->data[i/2] > x; i /= 2) {heap->data[i] = heap->data[i/2];  // 上滤}heap->data[i] = x;
}// 删除最小堆的根节点(最小值)
int DeleteMin(MinHeap* heap) {int parent, child;int minItem, x;if (heap->size == 0) return -1;minItem = heap->data[1];x = heap->data[heap->size--];for (parent = 1; parent * 2 <= heap->size; parent = child) {child = parent * 2;if ((child != heap->size) && (heap->data[child] > heap->data[child+1]))child++;  // 选择较小的子节点if (x <= heap->data[child]) break;else heap->data[parent] = heap->data[child];  // 下滤}heap->data[parent] = x;return minItem;
}// 构建最小堆
void BuildHeap(MinHeap* heap, int n) {int i;for (i = n/2; i > 0; i--) {int parent, child;int x = heap->data[i];for (parent = i; parent * 2 <= heap->size; parent = child) {child = parent * 2;if ((child != heap->size) && (heap->data[child] > heap->data[child+1]))child++;if (x <= heap->data[child]) break;else heap->data[parent] = heap->data[child];}heap->data[parent] = x;}
}// 计算哈夫曼树的WPL
int CalculateWPL(int weights[], int n) {MinHeap* heap = CreateHeap(n);int i, wpl = 0;// 初始化堆heap->size = n;for (i = 1; i <= n; i++) {heap->data[i] = weights[i-1];}BuildHeap(heap, n);// 构建哈夫曼树并计算WPLfor (i = 1; i < n; i++) {int x = DeleteMin(heap);int y = DeleteMin(heap);wpl += x + y;  // 每次合并两个最小值,累加权重和Insert(heap, x + y);  // 合并后的新节点插入堆中}free(heap->data);free(heap);return wpl;
}int main() {int n, i;int weights[MAXN];// 读取输入scanf("%d", &n);for (i = 0; i < n; i++) {scanf("%d", &weights[i]);}// 计算并输出WPLprintf("%d\n", CalculateWPL(weights, n));return 0;
}    
http://www.dtcms.com/a/288602.html

相关文章:

  • UDP中的单播,多播,广播
  • 【RAG Agent】Deep Searcher实现逻辑解析
  • 【Unity3D实例-功能-移动】角色移动-通过WSAD(CharacterController方式)
  • 【STM32实践篇】:串口通信
  • Qwen3-8B 的 TTFT 性能分析:16K 与 32K 输入 Prompt 的推算公式与底层原理详解
  • 吴恩达机器学习笔记(3)—线性代数回顾(可选)
  • 【Django】DRF API版本和解析器
  • HTML Style 对象深度解析:从基础到高级应用
  • 上电复位断言的自动化
  • 【数据结构】双向循环链表的实现
  • 18.TaskExecutor获取ResourceManagerGateway
  • 【MySQL】索引中的页以及索引的分类
  • 【Nature Communications】GaN外延层中位错辅助的电子和空穴输运
  • PHPStorm携手ThinkPHP8:开启高效开发之旅
  • selenium4 web自动化测试
  • pip关于缓存的用法
  • minizinc学习记录
  • 如何优雅解决缓存与数据库的数据一致性问题?
  • Docker实践:使用Docker部署WhoDB开源轻量级数据库管理工具
  • 飞船躲避陨石小游戏流量主微信抖音小程序开源
  • 【ESP32设备通信】-使用Modbus RTU读取传感器数据
  • 嵌入式硬件篇---按键
  • 嵌入式硬件篇---机械臂运动学解算(3自由度)
  • CentOS 服务器docker pull 拉取失败
  • 在vue中遇到Uncaught TypeError: Assignment to constant variable(常亮无法修改)
  • 后台管理系统登录模块(双token的实现思路)
  • 音视频学习(四十一):H264帧内压缩技术
  • 通俗易懂神经网络:从基础到实现
  • 【JavaFX国产化适配】快捷键注册(检测快捷键冲突、注册事件)
  • Syncthing实时共享同步数据 服务器数据备份软件(linux、windows)