数据结构之最优二叉树

news2024/9/28 19:19:10

数据结构之最优二叉树

  • 1、最优二叉树
  • 2、哈夫曼编码

  数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用计算机解决问题的效率服务。
  数据结构是指数据元素的集合及元素间的相互关系和构造方法。元素之间的相互关系是数据的 逻辑结构,数据元素及元素之间关系的存储称为 存储结构(或物理结构)。数据结构按照逻辑关系的不同分为 线性结构非线性结构两大类,其中,非线性结构又可分为树结构和图结构。
  树结构是一种非常重要的非线性结构,该结构中的一个数据元素可以有两个或两个以上的直接后继元素,树可以用来描述客观世界中广泛存在的层次结构关系。
  二叉树是 n(n≥0)个结点的有限集合,它或者是空树(n=0),或者是由一个根结点及两棵不相交的且分别称为左、右子树的二叉树所组成。

1、最优二叉树

  最优二叉树又称为哈夫曼树,它是一类带权路径长度最短的树。路径是从树中一个结点到另一个结点之间的通路,路径上的分支数目称为路径长度。
  树的路径长度是从树根到每一个叶子之间的路径长度之和。结点的带权路径长度为从该结点到树根之间的路径长度与该结点权值的乘积。
  树的带权路径长度为树中所有叶子结点的带权路径长度之和,记为
W P L = Σ k = 1 n w k l k WPL={\huge\Sigma}^n_{k=1}{\large w}_k {\large l}_k WPL=Σk=1nwklk
其中,n 为带权叶子结点数目,wk 为叶子结点的权值,lk为叶子结点到根的路径长度。
  哈夫曼树是指权值为 w1,w2,···,wn 的n个叶子结点的二又树中带权路径长度最小的二叉树。
  例如,下图所示的具有4个叶子结点的二叉树,其中以图 (b) 所示的二叉树带权路径长度最小。
在这里插入图片描述

  那么如何构造最优二叉树呢? 构造最优二叉树的哈夫曼算法如下。
  (1)根据给定的n个权值 {w1,w2,···,wn},构成n颗二叉树的集合F= (T1,T2,···,Tn},其中,每棵树 Ti 中只有一个带权为 wi 的根结点,其左、右子树均空。
  (2)在F中选取两棵权值最小的树作为左、右子树构造一棵新的二叉树,置新构造二叉树的根结点的权值为其左、右子树根结点的权值之和。
  (3)从F中删除这两棵树,同时将新得到的二叉树加入到F中。
  重复(2)、(3) 步,直到 F 中只含一棵树时为止,这棵树便是最优二叉树(哈夫曼树)。
  由此算法可知,以选中的两棵子树构成新的二叉树,哪个作为左子树,哪个作为右子树,并没有明确。所以,具有n 个叶子结点的权值为 w1,w2,···,wn 的最优二叉树不唯一,但其 WPL 值是唯一确定的。
  当给定了 n 个权值后,构造出的最优二叉树中的结点数目 m 就确定了,即 m=2×n-1,所以可用一维的结构数组来存储最优二叉树,下面举例说明。

#define MAXLEAFNUM 50						/*最优二叉树中的最多叶子数目*/
typedef struct nodef{
	char ch;								/*结点表示的字符,对于非叶子结点,此域不用*/
	int weight;								/*结点的权值*/
	int parent;								/*结点的父结点的下标,为0时表示无父结点*/
	int lchild,rchild;						/*结点的左、右孩子结点的下标,为0 时表示无孩子结点*/
}HuffmanTree[2*MAXLEAFNUM];
typedef char* HuffmanCode[MAXLEAFNUM+1];

  【函数】创建最优二叉树。

void createHTree(HuffmanTree HT, char *c, int *w,int n)
/*数组 c[0..n-1]和 w[0..n-1]存放了n个字符及其概率,构造哈夫曼树HT*/
{
	int i,sl,s2;
	if (n <= 1) return;
	for(i=l; i<-n; i++){ /*根据n个权值构造n只有根结点的二叉树*/
		HT[i].ch = c[i-l]; 
		HT[i].weight = w[i-l];
		HT[i].parent=HT[i].lchild=HT[i].rchild=0;
	}
	for(;i<2*n;++i) { /*初始化*/
		HT[i].parent=0;
		HT[i].lchild=0; 
		HT[i].rchild=0;
	}
	for(i= n+l; i<2*n; i++)
		/*从HT[l..i-1]中选择 parent 为0且weight最小的两棵树,其序号为 s1和s2*/
		select(HT,i-1,s1,s2);
		HT[sl].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[sl].weight + HT[s2].weight;
	}/*for*/
}/* createHTree*/

2、哈夫曼编码

  若对每个字符编制相同长度的二进制码,则称为等长编码。例如,英文字符集中的 26个字符可采用5 位二进制位串表示,按等长编码格式构造一个字符编码表。发送方按照编码表对信息原文进行编码后送出电文,接收方对接收到的二进制代码按每 5位一组进行分割,通过字符的编码表即可得到对应字符,实现译码。
  等长编码方案的实现方法比较简单,但对通信中的原文进行编码后,所得电文的码串过长不利于提高通信效率,因此希望缩短码串的总长度。如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,那么传送的电文码串总长度则可减少。
  如果要设计长度不等的编码,必须满足下面的条件:任一字符的编码都不是另一个字符的编码的前缀,这种编码也称为前缀码。对给定的字符集 D={d1,d2,···,dn} 及字符的使用频率W={w1,w2,···,wn},构造其最优前缀码的方法为: 以d1,d2,···,dn 作为叶子结点,w1,w2,···,wn 作为叶子结点的权值,构造出一棵最优二叉树,然后将树中每个结点的左分支标上 0,右分支标上1,则每个叶子结点代表的字符的编码就是从根到叶子的路径上的0、1组成的串。
  例如,设有字符集{a,b,c,d,e}及对应的权值集合{0.30,0.25,0.15,0.22,0.08},按照构造最优二叉树的哈夫曼方法:先取字符 c和e所对应的结点构造一棵二叉树(根结点的权值为c和e的权值之和),然后与 d 对应的结点分别作为左、右子树构造二叉树,之后选a 和b所对应的结点作为左、右子树构造二叉树,最后得到的最优二叉树 (哈夫曼树)如下图所示。其中,字符a的编码为 00,字符b、c、d、e的编码分别为 01、100、11、101。
前缀编码示例

  译码时就从树根开始,若编码序列中当前编码为 0,则进入当前结点的左子树;为1 则进入右子树,到达叶子时一个字符就翻译出来了,然后再从树根开始重复上述过程,直到编码序列结束。例如,若编码序列101110000100 对应的字符编码采用上图所示的树进行构造,则可翻译出字符序列"edaac"。
  【函数】根据给定的哈夫曼树,从每个叶子结点出发追溯到树根,逆向找出最优二叉树中叶子结点的编码。

void HuffmanCoding(HuffmanTree HT, HuffmanCode HC,int n)
/*n个叶子结点在哈夫曼树HT中的下标为 1~n,第i(l≤i≤n)个叶子的编码存放HC[i]中*/
{
	char *cd; 
	int i, start, c, f;
	if(n <= 1) return;
	cd =(char *)malloc(n*sizeof(char));
	cd[n-1]='\0';
	for(i= l; i<= n;+){
		start = n-l;
		for(c = i,f= HT[i],parent; f!=0; c=f,f=HT[f].parent)
			if (HT[f].lchild == c) cd[--start] = '0';
			else cd[--start]='1';
		HC[i] =(char*)malloc((n-start)*sizeof(char));
		strcpy(HC[il,&cd[start]);
	}/*for*/
	free(cd);
}/*HuffmanCoding*/

  利用哈夫曼树译码的过程为:从根结点出发,按二进制位串中的0和1确定是进入左分支还是右分支,当到达叶子结点时译出一个字符。若位串未结束,则回到根结点继续上述译码过程,直到位串结束。
  【函数】用最优二又树进行译码

void Decoding(HuffmanTree HT,int n,char *buf) 
/*利用具有n个叶子结点的最优二叉树(存储在数组 HT 中) 进行译码,叶子的下标为 1~n*/
/*buff 指向二进制位串编码序列*/
{
	int p=2*n-1;
	while (*buff){
		if((*buff) == '0') p = HT[p].lchild;		/*进入左分支*/
		else p = HT[p].rchild;						/*进入右分支*/
		if(HT[p].lchild==0 && HT[p].rchild==0){		/*到达一个叶子结点*/
			printf("%c", HT[p].ch);
			p=2*n-1;								/*回到树根*/
		}/*if*/
		buff++;
	}/*while*/
}/*Decoding*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1407810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elment UI的el-table-column表头旁边有点击按钮类似的操作

Elment UI的el-table-column表头旁边有点击按钮类似的操作 <el-table-column fixed"right" label"操作" ><!-- 表头 --> {{-- <template slot"header" header"scope">--}} {{-- <span…

uniapp设置隐藏原生导航栏(3)

1、单个页面隐藏 在pages.json里配置 (第一种方式) {"path": "pages/home/index","style": {"navigationBarTitleText": "首页","navigationStyle": "custom" // 使用自定义导航栏&#xff0c;系统会关…

在 EggJS 中实现 Redis 上锁

配置环境 下载 Redis Windows 访问 https://github.com/microsoftarchive/redis/releases 选择版本进行下载 - 勾选 [配置到环境变量] - 无脑下一步并安装 命令行执行&#xff1a;redis-cli -v 查看已安装的 Redis 版本&#xff0c;能成功查看就表示安装成功啦~ Mac brew i…

企业内部知识库搭建教程,赶紧收藏起来

在企业运营中&#xff0c;内部知识库搭建是一项重要的挑战&#xff0c;并需要合理的规划与管理。尤其对于中大型企业&#xff0c;内部知识库能够提高工作效率&#xff0c;减轻员工工作压力与突发事件的处理的困扰。下面给大家提供一份完整的内部知识库搭建教程&#xff0c;快看…

如何自信地部署人工智能(AI)

提升业务价值的人工智能方法 人工智能 (AI) 已经在变革业务、降低成本、最大限度地提高收入并增强客户体验。许多组织开始注意到&#xff1a;到 2025 年&#xff0c;AI 市场规模预计将增长到 3909 亿美元&#xff0c;而且该领域的行业也呈现出类似的发展趋势——例如&#xff…

常用界面设计组件 —— 容器组件

2.6 容器组件2.6.1 QGroupBox2.6.2 QScrollArea2.6.3 QToolBox2.6.4 QTabWidget2.6.5 QStackedWidget 2.6 容器组件 为了将界面上的各个组件的分布设计得更加美观&#xff0c;经常 使用一些容器类&#xff0c;如 QgoupBox、QtabWidget、 QToolBox等。 2.6.1 QGroupBox 实例效…

YOLOv7调用摄像头检测报错解决

yolov7detect.py文件调用本地摄像头&#xff0c;把source参数设为0 parser.add_argument(--source, typestr, default0, helpsource) # file/folder, 0 for webcam 报错&#xff1a;cv2.error: OpenCV(3.4.2) 一堆地址:The function is not implemented. Rebuild the library…

洛谷 P1705 爱与愁过火

测试用例 5 2 8 1 7 2 5 4#include<iostream> #include<string.h> using namespace std; int m, r, n; int a[100]; int visit[100] {0}; int sum 0; void traceback(int s,int price,int next){if(s r){if (price > n)sum;return ;}for (int i next ;i &…

Linux命令大全(超详细版)

一 ~ 四章 【点击此处查看】 五、shell 编程 5.1、shell 概述 5.1.1 shell 是什么 Shell是一个命令行解释器&#xff0c;它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序&#xff0c;用户可以用Shell来启动、挂起、停止甚至是编写一些程序。 Shell还是…

理解分布式存储的真实成本 - 10PB的硬件和软件

我们最近与一家大型银行的首席信息官进行了一次对话。他们是全球系统性重要银行之一——规模极其庞大。这位CIO决定将MinIO引入为数据分析计划的对象存储。这个部署从抵押贷款、交易和新闻平台收集数据&#xff0c;以运行Spark和其他分析工具&#xff0c;为银行提供洞察力。Min…

深入理解Java中的队列(Queue)

目录 一、什么是队列&#xff08;Queue&#xff09;&#xff1f; 二、队列中的常用方法 三、Java中的队列接口和实现类 1. LinkedList 2. ArrayDeque 3. PriorityQueue 四、队列的应用场景 1.消息队列 2.线程池任务调度 3.缓存淘汰策略 4.网络请求调度 5.广度优先搜索&#xff…

肺癌相关文献6

第十四篇 Classification of lung adenocarcinoma based on stemness scores in bulk and single cell transcriptomes IF&#xff1a;6.0 中科院分区:2区 生物学WOS分区&#xff1a;Q1被引次数&#xff1a; 4 背景&#xff1a;癌细胞具有无限期自我更新和增殖的能力[2]。在一…

# [NOI2019] 斗主地 洛谷黑题题解

[NOI2019] 斗主地 题目背景 时限 4 秒 内存 512MB 题目描述 小 S 在和小 F 玩一个叫“斗地主”的游戏。 可怜的小 S 发现自己打牌并打不过小 F&#xff0c;所以他想要在洗牌环节动动手脚。 一副牌一共有 n n n 张牌&#xff0c;从上到下依次标号为 1 ∼ n 1 \sim n 1∼…

UV紫外激光打标机的优缺点是什么

​ UV紫外激光打标机具有以下优点&#xff1a; 1. 精度高&#xff1a;紫外激光打标机的光束质量好&#xff0c;聚焦光斑小&#xff0c;可以实现在各种材料上进行超精细打标。 2. 速度快&#xff1a;由于紫外激光的独特特性&#xff0c;打标速度非常快&#xff0c;提高了生产效…

23111 C++ day1

思维导图 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 要求使用C风格字符串完成 #include <iostream> #include<array>using namespace std;int main() {int a0,A0,num0,space0,other0;array<char…

中国大模型迎来“95后” 百度奖学金发掘百位“未来AI技术领袖”

在人工智能掀起的科技革命和产业变革浪潮下&#xff0c;大模型成为最受关注的研究领域。1月22日&#xff0c;第十一届百度奖学金颁奖典礼在北京举行&#xff0c;来自全球顶尖高校及科研机构的10位“未来AI技术领袖”脱颖而出&#xff0c;他们平均年龄仅27岁&#xff0c;其中8人…

Oracle触发器简单应用示例

目录 一、应用描述 【1】、应用场景&#xff1a; 【2】、具体场景&#xff1a; 二、表结构介绍 【1】表名介绍&#xff1a; 【2】表结构&#xff1a; 三、设置触发器 一、应用描述 【1】、应用场景&#xff1a; 现有一张库存明细以及销售明细表&#xff0c;销售明细表发生…

python合并多个dict---合并多个字典值---字典值相加

文章目录 序多个dict同key值相加collection.Counter传参重载号 多个dict合并练习 序 主要是借助Counter、函数传参和运算符重载&#xff01;各有优劣&#xff01; 多个dict同key值相加 collection.Counter 借助collections.Counter&#xff0c;但是它只适用于值为整数或者小…

扭蛋机小程序开发,让扭蛋迷体验到扭蛋的趣味性

扭蛋机作为盲盒的前身&#xff0c;也是深受大众的欢迎&#xff0c;十几到几十不等的价格就可以让消费者体验到幸福感。扭蛋机具有价格低、性价比高的特点&#xff0c;扭蛋中的主题商品也都是经典热门动漫&#xff0c;具有较高的收藏价值&#xff0c;吸引了不少的扭蛋迷。 随着…

企业新闻稿怎么写?纯干货!

企业新闻稿是企业宣传的重要营销方式&#xff0c;新闻稿件的质量直接决定你的宣传效果&#xff0c;企业新闻稿怎么写&#xff0c;接下来伯乐网络传媒就来给大家分享一些企业新闻稿写作心得&#xff0c;纯干货&#xff0c;建议收藏起来慢慢看&#xff01; 一、企业新闻稿的组成要…