数据结构与算法-哈夫曼树与图

news2024/11/19 10:24:00

在这里插入图片描述
🌞 “永远积极向上,永远豪情满怀,永远热泪盈眶!”


哈夫曼树与图

  • 🎈1.哈夫曼树
    • 🔭1.1树与二叉树的转换
    • 🔭1.2森林与二叉树的转换
    • 🔭1.3哈夫曼树
      • 🔎1.3.1哈夫曼树的概念
      • 🔎1.3.2哈夫曼树的构造
      • 🔎1.3.3例题
  • 🎈2.图
    • 🔭2.1图的定义
    • 🔭2.2图的基本术语
    • 🔭2.3图的抽象数据类型
    • 🔭2.4图的存储结构
      • 📖2.4.1邻接矩阵存储
        • ✅2.4.1.1邻接矩阵表示的类定义
        • ✅2.4.1.2创建图
        • ✅2.4.1.3定位操作-查找顶点信息在顶点数组中的下标
        • ✅2.4.1.4创建有向图或无向图
        • ✅2.4.1.5创建有向网或无向网
        • ✅2.4.1.6计算顶点的度数-有向图为例
        • ✅2.4.1.7以有向图为例

🎈1.哈夫曼树

🔭1.1树与二叉树的转换

由于二叉树和树均可以用二叉链表作为存储结构,因此以二叉链表为媒介可以倒数树和二叉树的对应关系。一棵树可以找到唯一的一棵二叉树与之对应。反之,一棵右子树为空的二叉树也可以转换成对应的树。

📝将一棵树转化为二叉树的方法如下:

  1. 加线:将树中所有相邻的兄弟之间加一条线。
  2. 抹线:保留树中每个结点与其第一个孩子结点之间的连线,删除它与其他孩子结点之间的连线。
  3. 旋转:以右侧有结点连线的结点为轴心,将其右侧结点顺时针旋转45°,使之成为一棵层次分明的二叉树。
    在这里插入图片描述

在这里插入图片描述

🔭1.2森林与二叉树的转换

从树和二叉树的转换方式知,任何一棵树转换成二叉树,二叉树的右子树必为空。由此,我们可以把森林中的第二棵树的根结点看作第一棵树的根结点的兄弟,第三棵树的根结点看成是第二棵树的根结点的兄弟。
在这里插入图片描述

🔭1.3哈夫曼树

🔎1.3.1哈夫曼树的概念

哈夫曼树,又称最优二叉树,是一类树的带权路径长度最小的二叉树。

  • 路径:从一个祖先结点到子孙结点之间的分支构成这两个结点间的路径。
  • 路径长度:路径上分支的数目。
  • 树的路径长度:从根到每个结点的路径长度之和。
  • 结点的权:根据应用的需要可以给树的结点赋予权值。
  • 结点的带权路径长度:从根到该结点的路径长度与该结点权的乘法。
  • 树的带权路径长度:树中所有叶子结点的带权路径长度之和。
    带权路径长度最小的二叉树称为哈夫曼树,也称最优二叉树。

🔎1.3.2哈夫曼树的构造

在这里插入图片描述

🔎1.3.3例题

在这里插入图片描述
🧩定理:对于具有n个叶子结点的哈夫曼树,共有2n-1个结点,其中有n-1个非叶子结点。

🎈2.图

🔭2.1图的定义

称有序二元组G=(V,E)是一个图,若其中V是一个非空有限集合(或称顶点集),V中的数据元素称为顶点,EV上的二元关系,称E为边集。
(1).若E中的顶点对(或序偶)(u,v)是无序的,则称G为无向图,称(u,v)G的一条无向边,显然,(u,v)(v,u)是指同一条边。
(2).若E中的顶点对(或序偶)(u,v)是有序的,则称G为有向图。称(u,v)G的一条有向边(或弧),其中,称u为弧尾(或始点),称v为弧头(或终点)。

🔭2.2图的基本术语

  1. 端点、邻接点、自环和孤立点:在一个无向图G=(V,E)中,若e=(u,v)G中的一条边,uv称为边e的两个端点,称边e关联uv,也称u邻接v,或v邻接uuv称为边e=(u,v)的邻接点;若u=v,称(u,v)G的自环。对于任意的u属于V,若不存在任何边关联u,说明顶点u是孤立点。
  2. 完全图:令G=(V,E)为一个图,且|V|=n,|E|=m。若无向图中每两个顶点间都存在一条边,或在有向图中每两个顶点间都存在着方向相反的两条有向边,则称此图为完全图。显然,无向图包含n(n-1)/2条边,有向图包含n(n-1)条边。
  3. 稀疏图和稠密图:边数很少的图(m<nlogn)称为稀疏图,反之称为稠密图。
  4. 顶点的度、出度和入度:在无向图G=(V,E)中,对于每一个v属于V,称关联顶点v的边数为顶点v的度数,记为d(v).在有向图G=(V,E)中,对于每一个v属于V,称以v为始点的边的条数为v的出度,称以v为终点的边的条数为v的入度。在无向图中,顶点的度数之和与边数有如下关系:

在这里插入图片描述
在有向图中,顶点的度数之和与边数有如下关系:
在这里插入图片描述

  1. 子图、真子图和生成子图:G=(V,E),H=(V1,E1)是两个图。
    在这里插入图片描述

  2. 路径、路径长度、简单路径和初等路径:
    在这里插入图片描述

  3. 回路、简单回路和初等回路:
    在这里插入图片描述

  4. 连通、连通图和连通分量:
    在这里插入图片描述

  5. 连通、强连通和强连通分量:
    在这里插入图片描述

  6. 权和网:在某些图中,边或弧上具有与它相关的数据信息称之为权。在实际应用中,权值可以有某种含义。例如,在城市交通线路的图中,边上的权值可以来表示该线路上的长度或交通费用等。边上带权的图称为带权图,也称网。

  7. 生成树:包含Gn个顶点的极小连通子图称为图G的生成树。一棵具有n个顶点的生成树有且仅有n-1条边。


🔎例题:图G=(V,E)是一个非连通无向图,共有36条边,则该图至少有多少个顶点?

该非连通无向图至少由一个顶点和一个连通无向图组成。(n-1)n/2=36,n=9,所以该图至少有10个顶点。

🔭2.3图的抽象数据类型

ADT Graph{
    数据对象:
      D = V = {ai|1<=i<=n,ai属于Elemtype}
    数据关系:
      R = E = {(ai,aj)|1<=i<=n,1<=j<=n,ai,aj属于D}
    基本操作:
    InitGraph(&g,V,E);//初始化创建一个图
    DestroyGraph(&g);//摧毁图,释放图占用的存储空间
    LocateVex(g,v);//查找顶点v在图中的位置
    InsertVex(&g,v);//在图中插入一个顶点v
    DeleteVex(&g,v);//在图中删除一个顶点v
    Degree(g,v);//计算顶点v的度数
    DFETraverse(g,v);//从顶点v出发对图进行深度优先遍历
    BFSTraverse(g,v);//从顶点v出发对图进行广度优先遍历
    }ADT Graph

🔭2.4图的存储结构

📖2.4.1邻接矩阵存储

在这里插入图片描述
在这里插入图片描述
🔎图的邻接矩阵存储结构具有如下特点:

  1. 无向图的邻接矩阵是对称矩阵,实际存储时可以采用压缩矩阵存储。
  2. 有向图的邻接矩阵不一定对阵,因此,采用邻接矩阵存储具有n个顶点的有向图时,其存储结构的空复杂度为O(n2)。
  3. 无向图邻接矩阵的第i行(或第i列)中非0元素的个数,就是顶点i的度数。
  4. 有向图邻接矩阵的第i行中非0元素的个数,就是顶点i的出度,第i列中非0元素的个数,就是顶点i的入度。
  5. 利用邻接矩阵可以较容易地确定图中两顶点之间是否有边。但若要确实图的总边数,则要按行按列进行查询,耗费的时间代价较大。另外,邻接矩阵用数组表示时,静态数组的局限性不便于图的插入和删除操作,它们是邻接矩阵存储结构的局限性。
✅2.4.1.1邻接矩阵表示的类定义
#define _CRT_SECURE_NO_WARNINGS 1
#define MaxVex 20//预设最大顶点数
const int MAXINT = 0xfffffff;//最大整数,表示无穷大
typedef struct 
{
	VRType adj;//VRType为顶点关系类型,对无权图值为0或1
	InfoType info;//该弧相关信息
}ArcBox;
typedef struct
{
	VElemType vexs[MaxVex];//VElemType为顶点信息类型
	ArcBox arcs[MaxVex][MaxVex];//邻接矩阵,即边表
	int vexnum;//顶点数
	int arcnum;//边数
	int kind;//邻接矩阵的存储的图的种类:1有向图,2无向图,3有向网,4无向网
}MGraph;
class Graph
{
private:
	MGraph mg;
public:
	void CreateGraph();//创建图
	int LocateVex(VElemType x);//返回图中顶点x在顶点数组中的下标
	void CreateDG();//构造有向图
	void CreateUDG();//构造无向图
	void CreateDN();//构造有向网
	void CreateUDN();//构造无向网
	int DegreeGraph(VElemType x);//计算顶点的度数
	void ShortPath_DIJ(VElemType v);//求最短路径
	void Dispath(int dist[], int path[], int s[], VElemType x);//输出最短路径
	void Floyd();//Floyd算法求最短路径
	void Dispath(int dist[MaxVex][MaxVex]);//输出最短路径
};
✅2.4.1.2创建图
void Graph::CreateGraph()
{
	cout << "输入图的种类:1:有向图 2:无向图 3:有向网 4:无向网";
	cin >> mg.kind;
	switch (mg.kind)
	{
	case 1:CreateDG();//构造有向图
		break;
	case 2:CreateUDG();//构造无向图
		break;
	case 3:CreateDN();//构造有向网
		break;
	case 4:CreateUDN();//构造无向网
	}
}
✅2.4.1.3定位操作-查找顶点信息在顶点数组中的下标
int Graph::LocateVex(VElemType x)
{
	for (int i = 0; i < mg.vexnum; i++)
	{
		if (x == mg.vexs[i])
			return i;
		return -1;
	}
}
✅2.4.1.4创建有向图或无向图
void Graph::CreateDG()
{
	int i, j, h, t;
	VElemType u, v;
	int flag;//0表示没有弧信息,1表示有弧信息
	cin >> mg.vexnum >> mg.arcnum >> flag;
	for (int i = 0; i < mg.vexnum; i++)
	{
		cin >> mg.vexs[i];//构造顶点信息
	}
	for (i = 0; i < mg.vexnum; i++)
	{
		for (j = 0; j < mg.vexnum; j++)
		{
			mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
			mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
		}
	}
	for (i = 0; i < mg.arcnum; i++)
	{
		cin >> u >> v;
		h = LocateVex(u);
		t = LocateVex(v);
		if (flag)
		{
			cin >> mg.arcs[h][t].info;
		}
		mg.arcs[h][t].adj = 1;//1表示顶点相邻
		mg.arcs[t][h].adj = 1;//若为无向图加上这条
	}
}
✅2.4.1.5创建有向网或无向网
void Graph::CreateDN()
{
	int i, j, h, t, w;
	VElemType u, v;
	int flag;//0表示没有弧信息,1表示有弧信息
	cin >> mg.vexnum >> mg.arcnum >> flag;
	for (int i = 0; i < mg.vexnum; i++)
	{
		cin >> mg.vexs[i];//构造顶点信息
	}
	for (i = 0; i < mg.vexnum; i++)
	{
		for (j = 0; j < mg.vexnum; j++)
		{
			if (i == j)
			{
				mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
			}
			else
			{
				mg.arcs[i][j].adj = MAXINT;
			}
			mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
		}
	}
	for (i = 0; i < mg.arcnum; i++)
	{
		cin >> u >> v >> w;
		h = LocateVex(u);
		t = LocateVex(v);
		if (flag)
		{
			cin >> mg.arcs[h][t].info;
		}
		mg.arcs[h][t].adj = w;
		mg.arcs[t][h].adj = w;//若为无向网加上该赋值
	}
}
✅2.4.1.6计算顶点的度数-有向图为例
int Graph::DegreeGraph(VElemType x)
{
	int h = LocateVex(x);
	int count = 0;
	for (int i = 0; i < mg.vexnum; i++)
	{
		if (mg.arcs[h][i].adj && mg.arcs[h][i].adj != MAXINT)
			count++;
		if (mg.arcs[i][h].adj && mg.arcs[i][h].adj != MAXINT)
			count++;
	}
	return count;
}
✅2.4.1.7以有向图为例
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
typedef int VElemType;
typedef int VRType;
typedef int InfoType;
#define MaxVex 20//预设最大顶点数
const int MAXINT = 0xfffffff;//最大 整数,表示无穷大
typedef struct 
{
	VRType adj;//VRType为顶点关系类型,对无权图值为0或1
	InfoType info;//该弧相关信息
}ArcBox;
typedef struct
{
	VElemType vexs[MaxVex];//VElemType为顶点信息类型
	ArcBox arcs[MaxVex][MaxVex];//邻接矩阵,即边表
	int vexnum;//顶点数
	int arcnum;//边数
	int kind;//邻接矩阵的存储的图的种类:1有向图,2无向图,3有向网,4无向网
}MGraph;
class Graph
{
private:
	MGraph mg;
public:
	void CreateGraph();//创建图
	int LocateVex(VElemType x);//返回图中顶点x在顶点数组中的下标
	void CreateDG();//构造有向图
	void CreateUDG();//构造无向图
	void CreateDN();//构造有向网
	void CreateUDN();//构造无向网
	int DegreeGraph(VElemType x);//计算有向图顶点的度数
};
void Graph::CreateGraph()
{
	cout << "输入图的种类:1:有向图 2:无向图 3:有向网 4:无向网"<<endl;
	cout << "请输入:";
	cin >> mg.kind;
	switch (mg.kind)
	{
	case 1:CreateDG();//构造有向图
		break;
	case 2:CreateUDG();//构造无向图
		break;
	case 3:CreateDN();//构造有向网
		break;
	case 4:CreateUDN();//构造无向网
	}
}
int Graph::LocateVex(VElemType x)
{
	for (int i = 0; i < mg.vexnum; i++)
	{
		if (x == mg.vexs[i])
			return i;
	}
	return -1;
}
void Graph::CreateDG()
{
	int i, j, h, t;
	VElemType u, v;
	int flag;//0表示没有弧信息,1表示有弧信息
	cout << "请输入顶点数、边数以及是否有弧信息(0/1)";
	cin >> mg.vexnum >> mg.arcnum >> flag;
	cout << "请输入" << mg.vexnum << "个顶点:";
	for (int i = 0; i < mg.vexnum; i++)
	{
		cin >> mg.vexs[i];//构造顶点信息
	}
	for (i = 0; i < mg.vexnum; i++)
	{
		for (j = 0; j < mg.vexnum; j++)
		{
			mg.arcs[i][j].adj = 0;//用0初始化邻接矩阵
			mg.arcs[i][j].info = NULL;//用NULL初始化该弧的相关信息
		}
	}
	for (i = 0; i < mg.arcnum; i++)
	{
		cout << "请输入关联的两个顶点:";
		cin >> u >> v;
		h = LocateVex(u);
		t = LocateVex(v);
		if (flag)
		{
			cout << "请输入权值:";
			cin >> mg.arcs[h][t].info;
		}
		mg.arcs[h][t].adj = 1;//1表示顶点相邻
	}
}
int Graph::DegreeGraph(VElemType x)
{
	int h = LocateVex(x);
	int count = 0;
	for (int i = 0; i < mg.vexnum; i++)
	{
		if (mg.arcs[h][i].adj && mg.arcs[h][i].adj != MAXINT)
			count++;
		if (mg.arcs[i][h].adj && mg.arcs[i][h].adj != MAXINT)
			count++;
	}
	cout << "该顶点的度数为:" << count << endl;
	return 0;
}
int main()
{
	Graph a;
	a.CreateGraph();
	a.DegreeGraph(1);
	a.DegreeGraph(2);
	a.DegreeGraph(3);
	a.DegreeGraph(4);
	return 0;
}

✅运行示例:
在这里插入图片描述

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

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

相关文章

大数据HCIE成神之路之数学(2)——线性代数

线性代数 1.1 线性代数内容介绍1.1.1 线性代数介绍1.1.2 代码实现介绍 1.2 线性代数实现1.2.1 reshape运算1.2.2 转置实现1.2.3 矩阵乘法实现1.2.4 矩阵对应运算1.2.5 逆矩阵实现1.2.6 特征值与特征向量1.2.7 求行列式1.2.8 奇异值分解实现1.2.9 线性方程组求解 1.1 线性代数内…

基于STM32单片机数字电压表自动切换量程及源程序

一、系统方案 1、本设计采用这STM32单片机作为主控器。 2、液晶1602显示。 3、内部ADC采集电压0-12V&#xff0c;自动切换档位。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 u8 i; u16 a,b,c,d; u16 adcx; float adc; unsigned char datas…

AIGC实战 - 使用变分自编码器生成面部图像

AIGC实战 - 使用变分自编码器生成面部图像 0. 前言1. 数据集分析2. 训练变分自编码器2.1 变分自编码器架构2.2 变分自编码器分析 3. 生成新的面部图像4. 潜空间算术5. 人脸变换小结系列链接 0. 前言 在自编码器和变分自编码器上&#xff0c;我们都仅使用具有两个维度的潜空间。…

Alien Skin Exposure2024免费版图片颜色滤镜插件

Alien Skin Exposure一款非常专业的图片后期处理软件&#xff0c;内含500多种照片滤镜。是一款图片后期处理功能非常强大的软件。这款软件可以对图片的后期效果做很好的处理。 打开Alien Skin Exposure软件&#xff0c;会显示下面这个界面&#xff0c;如图1. ExposureX8win-安…

爱奇艺大数据离在线混部

混部作为一种提高资源利用率、降低成本的的方案&#xff0c;被业界普遍认可。爱奇艺在云原生化与降本增效的过程中&#xff0c;成功将大数据离线计算、音视频内容处理等工作负载与在线业务进行了混部&#xff0c;并且取得了阶段性收益。本文重点以大数据为例&#xff0c;介绍从…

图解API设计风格,看一眼就忘不了了!

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 免责声明~ 任何文章不要过度深思&#xff01; 万事万物都经不起审视&#xff0c;因为世上没有同样的成长环境&#xff0c;也没有同样的认知水平&#xff0c;更「没有适用于所有人的解决方案…

反弹Shell

概述 反弹shell&#xff08;reverse shell&#xff09;就是控制端监听在某TCP/UDP端口&#xff0c;被控端发起请求到该端口&#xff0c;并将其命令行的输入输出转到控制端。reverse shell与telnet&#xff0c;ssh等标准shell对应&#xff0c;本质上是网络概念的客户端与服务端…

原型网络Prototypical Network的python代码逐行解释,新手小白也可学会!!-----系列7(承接系列6)

文章目录 前言一、原始代码---保存原型点,加载原型点二、代码逐行解释 前言 此部分为原型网络的两个函数&#xff0c;分别为保存原型点函数和加载原型点函数&#xff0c;与之前的系列相承接。 一、原始代码—保存原型点,加载原型点 def save_center(self,path):datas []for …

C/C++ 获取主机网卡MAC地址

MAC地址&#xff08;Media Access Control address&#xff09;&#xff0c;又称为物理地址或硬件地址&#xff0c;是网络适配器&#xff08;网卡&#xff09;在制造时被分配的全球唯一的48位地址。这个地址是数据链路层&#xff08;OSI模型的第二层&#xff09;的一部分&#…

端口号大揭秘:网络世界的“门牌号”有多牛?

大家好&#xff0c;今天我们来聊一聊网络中的端口号。如果你以为端口号只是冷冰冰的数字&#xff0c;那你就大错特错了。端口号&#xff0c;这些看似枯燥的数字背后&#xff0c;隐藏着一个个生动的故事。 目录 大家好&#xff0c;今天我们来聊一聊网络中的端口号。如果你以为端…

odoo17前端js框架的演化

odoo17发布了&#xff0c;从界面上看&#xff0c;变化还是很明显的&#xff0c;比16更漂亮了&#xff0c;本来以为源码不会发生太大的变化&#xff0c;结果仔细一瞧&#xff0c;变化也不小。 1、打包好的文件数量和大小发生了变化 打包好的文件从两个变成了一个&#xff0c;在…

适用于全部安卓手机的 5 大免费 Android 数据恢复

您是否面临这样一种情况&#xff0c;即在Android设备上丢失了一些重要文件&#xff0c;但不知道应该选择哪种Android数据恢复来取回它们&#xff1f; 如果您以前从未备份过Android数据&#xff0c;则很难解决问题。 本文将介绍排名前5位的免费Android数据恢复软件。 您可以获…

同花顺,通达信,东方财富股票竞价,早盘板块、概念、题材竞价数据接口

早盘板块、概念、题材竞价数据接口 量化接口地址&#xff1a;https://stockapi.com.cn 通过分析每天早盘的板块竞价&#xff0c;从而判断出今日主力资金的看好方向 地址&#xff1a; https://stockapi.com.cn/v1/base/bkjjzq?tradeDate2023-11-08再结合个股竞价数据筛选出自…

科大讯飞会议笔记本、GoodNotes、E人E本 功能及体验对比

科大讯飞会议笔记本、GoodNotes、E人E本功能及体验对比 【旧文档&#xff0c;怕失传】 通过对科大讯飞会议笔记本、基于iPad的GoodNotes以及E人E本的各项功能指标进行了实际对比&#xff0c;得出了以下结果&#xff1a; 在实际体验中&#xff0c;科大讯飞笔记本在录音方面表…

知道数字孪生发展的四个阶段,你就能明白数字孪生的真正价值了

数字孪生的发展经历了四个阶段。以下是每个阶段的详细描述&#xff1a; 1、数字孪生萌芽期&#xff1a;这个阶段以模型仿真驱动为特征。20世纪80年代以来&#xff0c;CAD、CAE、CAM等计算机建模、模拟仿真技术开始迅猛发展&#xff0c;并在制造业领域广泛应用。该阶段主要通过…

JSP基本表单和Request对象使用例子

表单的jsp&#xff1b; <%page contentType"text/html;charsetgbk" pageEncoding"UTF-8"%> <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><titl…

2023全球边缘计算大会深圳站-核心PPT资料下载

一、峰会简介 边缘计算&#xff0c;是指在靠近物或数据源头的一侧&#xff0c;采用网络、计算、存储、应用核心能力为一体的开放平台&#xff0c;就近提供最近端服务。其应用程序在边缘侧发起&#xff0c;产生更快的网络服务响应&#xff0c;满足行业在实时业务、应用智能、安…

excel中设置图表图例的位置

例如&#xff0c;在excel中已经做好了一个折线图&#xff1a; 可以看到&#xff0c;默认图例是在图表的右侧&#xff0c;减小了图的横向展示区域。我们可以把图例放到图的上边、或者下边。 双击图表&#xff1a; 鼠标放在图例上方&#xff0c;出现了浮动文字“图例”&#…

代码随想录算法训练营第二十七天|39 组合总和 40 组合总和II 131分割回文串

目录 39 组合总和 40 组合总和II 131分割回文串 39 组合总和 class Solution {List<List<Integer>>res new ArrayList<>();List<Integer>newList new LinkedList<>();public List<List<Integer>> combinationSum(int[] candid…

【算法挨揍日记】day22——面试题 17.16. 按摩师、213. 打家劫舍 II

面试题 17.16. 按摩师 面试题 17.16. 按摩师 题目描述&#xff1a; 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在每次预约服务之间要有休息时间&#xff0c;因此她不能接受相邻的预约。给定一个预约请求序列&#xff0c;替按摩师找…