C++ 数据结构 哈弗曼树的制作

2023-11-07 08:15
文章标签 c++ 数据结构 制作 弗曼

本文主要是介绍C++ 数据结构 哈弗曼树的制作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 
输入
abbccc$
输出
9
样例输入 Copy
hello world$
样例输出 Copy
32
 
 

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MAX_SIZE  1000typedef char elemtype;//带权值的二叉树
typedef struct BiTNode {elemtype data;int weight; //权重struct BiTNode* lchild, * rchild; /*左右孩子指针*/
}BiTNode, * BiTree;//用单链表表示森林
typedef struct linkNode {BiTree tree;struct linkNode* next;
}LinkNode, * Forest;//创建森林
int createForest(Forest& forest)
{//待补全,读入字符串,以‘$'为结束符,根据每个字符出现频率为权值,构造森林。并返回森林中树的个数int count = 0; // 森林中树的个数BiTree tree;LinkNode* p = forest;char ch;char list[128] = {0};scanf("%c", &ch);while (ch != '$') {		list[ch] += 1;scanf("%c", &ch);}for (int i = 0; i < 128; i++) {if (!list[i])continue;tree = (BiTNode*)malloc(sizeof(BiTNode));tree->data = i;tree->weight = list[i];tree->lchild = NULL;tree->rchild = NULL;LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));newNode->tree = tree;newNode->next = NULL;p->next = newNode;p = p->next;count++;}	 	 return count;
}void sortForest(Forest forest)
{int count = 0;LinkNode* p = forest->next;BiTree* trees = (BiTree*)malloc(sizeof(BiTree) * MAX_SIZE);// 将森林中所有的树存储到数组中while (p != NULL) {trees[count++] = p->tree;p = p->next;}// 使用冒泡排序将树按照权值从小到大排序for (int i = 0; i < count - 1; i++) {for (int j = 0; j < count - i - 1; j++) {if (trees[j]->weight > trees[j + 1]->weight) {BiTree tmp = trees[j];trees[j] = trees[j + 1];trees[j + 1] = tmp;}}}// 将排好序的树重新插入森林中p = forest->next;for (int i = 0; i < count; i++) {p->tree = trees[i];p = p->next;}free(trees);
}BiTree createHuffmanTree(Forest forest)
{// 将森林中的所有树按照权值从小到大排序sortForest(forest);// 合并森林中的树,直到只剩下一棵树为止while (forest->next->next != NULL) {BiTree t1 = forest->next->tree;BiTree t2 = forest->next->next->tree;// 创建新的二叉树节点,作为t1和t2的父节点BiTree newNode = (BiTree)malloc(sizeof(BiTNode));newNode->data = '#';newNode->weight = t1->weight + t2->weight;newNode->lchild = t1;newNode->rchild = t2;// 将新节点插入森林中,并删除t1和t2LinkNode* newLinkNode = (LinkNode*)malloc(sizeof(LinkNode));newLinkNode->tree = newNode;newLinkNode->next = forest->next->next->next;forest->next->next->next = newLinkNode;forest->next = forest->next->next->next;// 重新排序森林sortForest(forest);}// 返回剩下的最后一棵树,即哈夫曼树return forest->next->tree;
}void calculateEncodingLength(BiTNode* root, int depth, int& totalLength) {if (!root) {return;}if (!root->lchild && !root->rchild) {totalLength += depth * root->weight;}calculateEncodingLength(root->lchild, depth + 1, totalLength);calculateEncodingLength(root->rchild, depth + 1, totalLength);
}int main()
{Forest forest = (linkNode*)malloc(sizeof(linkNode));//森林的单链表包含一个头结点,头结点符号‘$'forest->tree = (BiTNode*)malloc(sizeof(BiTNode));forest->tree->data = '$';forest->next = NULL;createForest(forest);BiTree root = createHuffmanTree(forest);int totalLength = 0;calculateEncodingLength(root, 0, totalLength);printf("%d\n",totalLength);}

这篇关于C++ 数据结构 哈弗曼树的制作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/362368

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提