C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作

news2024/12/24 3:21:37

文章目录

  • 写在前面
  • 哈夫曼树及哈夫曼编码的算法实现
    • 实验内容
    • 代码实现
  • 图的基本操作
    • 实验内容
    • 代码实现

写在前面

本篇实验代码非本人写,代码源自外部,经调试解决了部分warning和error后在本地vs上可以正常运行,如有运行失败可换至vs

未来会重构实现该两个实验


哈夫曼树及哈夫曼编码的算法实现

实验内容

内容要求:

1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树
2、建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4、译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。

测试数据:
输入字符串“thisprogramismyfavourite”,完成这28个字符的编码和译码。

代码实现

#include<iostream>
#include<string.h>
#include<queue>
#define MAX 10000 
using namespace std;
char a[100], buff[1024], p;
typedef struct
{
	char letter, * code;
	int weight;
	int parent, lchild, rchild;
}HTNode, * HuffmanTree;

int n;
char coding[100];

int Min(HuffmanTree& HT, int i)
{
	int j;
	int k = MAX;
	int flag=0;
	for (j = 0; j <= i; ++j)
	{
		if (HT[j].weight < k && HT[j].parent == 0)
		{
			k = HT[j].weight;
			flag = j;
		}
	}
	HT[flag].parent = 1;
	return flag;
}

void Select(HuffmanTree& HT, int i, int& s1, int& s2)
{
	s1 = Min(HT, i);
	s2 = Min(HT, i);
}

void CreateHuffmanTree(HuffmanTree& HT, char t[], int w[])
{
	int m;
	int i, s1, s2;
	if (n <= 1)
		return;
	m = 2 * n - 1; 
	HT = new HTNode[m + 1];
	for (i = 0; i < n; i++)
	{
		char arr[] = "0";
		char* pa = arr;
		HT[i].code = pa;
		HT[i].parent = 0;
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].letter = t[i];
		HT[i].weight = w[i];
	}
	for (i = n; i <= m; i++)
	{
		char arr[] = "0";
		char* pa = arr;
		HT[i].code = pa;
		HT[i].parent = 0;
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].letter = ' ';
		HT[i].weight = 0;
	}
	cout << "********************************" << endl;
	for (i = n; i < m; i++)
	{
		Select(HT, i - 1, s1, s2);

		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}

void CreatHuffmanCode(HuffmanTree HT)
{
	int start, c, f;
	int i;
	char* cd = new char[n];
	cd[n - 1] = '\0';
	cout << "字符编码为:" << endl;
	for (i = 0; i < n; i++)
	{
		start = n - 1;
		c = i;
		f = HT[i].parent;
		while (f != 0) 
		{
			--start;
			if (HT[f].lchild == c) 
			{
				cd[start] = '0';
			}
			else 
			{
				cd[start] = '1';
			}
			c = f;
			f = HT[f].parent;
		}
		HT[i].code = new char[n - start];
		strcpy(HT[i].code, &cd[start]);
		cout << HT[i].letter << ":" << HT[i].code << endl;
	}
	delete[] cd;
}

void HuffmanTreeDecode(HuffmanTree HT, char cod[], int b)  
{
	char sen[100];
	char temp[50];
	char voidstr[] = " ";
	int t = 0;
	int s = 0;
	int count = 0;
	for (int i = 0; i < b; i++)
	{
		temp[t++] = cod[i];
		temp[t] = '\0';
		for (int j = 0; j < n; j++) 
		{
			if (!strcmp(HT[j].code, temp)) 
			{
				sen[s] = HT[j].letter;
				s++;
				count += t;
				strcpy(temp, voidstr);
				t = 0;
				break;
			}
		}
	}
	if (t == 0) 
	{
		sen[s] = '\0';
		cout << "译码为:" << endl;
		cout << sen << endl;
	}
	else 
	{
		cout << "二进制源码有错!从第" << count + 1 << "位开始" << endl;
	}
}

int main()
{
	HuffmanTree HT;
	int b[100]={0};
	int i, j;
	int symbol = 1, x, k;
	cout << "请输入一段文字:";
	cin >> buff;
	int len = (int)strlen(buff);
	for (i = 0; i < len; i++)
	{
		for (j = 0; j < n; j++)
		{
			if (a[j] == buff[i])
			{
				b[j] = b[j] + 1;
				break;
			}
		}
		if (j >= n)
		{
			a[n] = buff[i];
			b[n] = 1;
			n++;
		}
	}
	cout << "字符和权值信息如下" << endl;
	for (i = 0; i < n; i++)
	{
		cout << "字符:" << a[i] << "  权值:" << b[i] << endl;
	}
	CreateHuffmanTree(HT, a, b);
	CreatHuffmanCode(HT);
	cout << "文字编码为:\n";
	for (int i = 0; i < len; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (buff[i] == HT[j].letter)
			{
				cout << HT[j].code;
				break;
			}
		}
	}
	cout << "\n译码:" << endl;
	while (1)
	{
		cout << "请输入要译码的二进制字符串,输入'#'结束:";
		x = 1;
		k = 0; 
		symbol = 1;
		while (symbol) 
		{
			cin >> p;
			if (p != '1' && p != '0' && p != '#') 
			{
				x = 0;
			}
			coding[k] = p;
			if (p == '#')
				symbol = 0;
			k++;
		}
		if (x == 1) 
		{
			HuffmanTreeDecode(HT, coding, k - 1);
		}
		else 
		{
			cout << "有非法字符!" << endl;
		}
		cout << "是否继续?(Y/N):";
		cin >> p;
		if (p == 'y' || p == 'Y')
			continue;
		else
			break;
	}
	return 0;
}

图的基本操作

实验内容

分别用邻接矩阵和邻接表对如下有向图实现:
1.输出存储结果;
2.计算各结点的出度和入度,并输出;
3.实现图的深度优先遍历和广度优先遍历,并输出。

在这里插入图片描述

代码实现

#include<stdio.h>
#include<stdlib.h>

#define MAXVEX 50
int visit[MAXVEX];
int in_deg[MAXVEX];//入度
int out_deg[MAXVEX];//出度 

typedef struct
{
	int vertices[MAXVEX];
	int arc[MAXVEX][MAXVEX];
	int vexnum, arcnum;
}MGraph;

typedef struct queue
{
	int* pBase;
	int front, rear;
}QUEUE;

void init_queue(QUEUE* Q)
{
	Q->pBase = (int*)malloc((sizeof(int)) * MAXVEX);
	Q->front = 0;
	Q->rear = 0;
}

bool isfull_queue(QUEUE* Q)
{
	if (((Q->rear + 1) % MAXVEX) == Q->front)
		return true;
	else
		return false;
}

bool isempty_queue(QUEUE* Q)
{
	if (Q->rear == Q->front)
		return true;
	else
		return false;
}

void in_queue(QUEUE* Q, int val)
{
	if (isfull_queue(Q))
		return;
	Q->pBase[Q->rear] = val;
	Q->rear = (Q->rear + 1) % MAXVEX;
}

int out_queue(QUEUE* Q)
{
	int temp = 0;
	if (isempty_queue(Q))
		return 0;
	temp = Q->pBase[Q->front];
	Q->front = (Q->front + 1) % MAXVEX;
	return temp;
}

void BFS(MGraph G, QUEUE* Q, int v)
{
	if (!visit[v]) {
		visit[v] = 1;
		printf("%d  ", G.vertices[v]);
		in_queue(Q, v);
	}
	while (!isempty_queue(Q)) {
		int temp = out_queue(Q);
		for (int i = 0; i < G.vexnum; i++) {
			if (G.arc[temp][i] != 0 && !visit[i]) {
				visit[i] = 1;
				printf("%d  ", G.vertices[i]);
				in_queue(Q, i);
			}
		}
	}
}

void BFST(MGraph G, QUEUE* Q)
{
	printf("\nBFS的遍历:");
	int i = 0;
	for (i = 0; i < G.arcnum; i++)
		visit[i] = 0;
	for (i = 0; i < G.vexnum; i++) {
		if (!visit[i])  BFS(G, Q, i);
	}
}

int LocateVex(MGraph G, int v)
{
	for (int i = 0; i < G.vexnum; i++) {
		if (G.vertices[i] == v)
			return i;
	}
	return 0;
}

void CreatMGraph(MGraph* G)
{
	int i = 0, j = 0;
	printf("请分别输入顶点数和边数: \n");
	scanf("%d%d", &(G->vexnum), &(G->arcnum));
	printf("请输入顶点信息:\n");
	for (i = 0; i < G->vexnum; i++)
		scanf("%d", &(G->vertices[i]));
	for (i = 0; i < G->vexnum; i++) {
		for (j = 0; j < G->vexnum; j++)
			G->arc[i][j] = 0;
	}
	printf("请输入构成边的两个顶点:  \n");
	for (i = 0; i < G->arcnum; i++) {
		int num, num1;
		scanf("%d%d", &num, &num1);
		int j = LocateVex(*G, num);
		int k = LocateVex(*G, num1);
		G->arc[j][k] = 1;
	}
}

void PrintMGraph(MGraph G)
{
	printf("*************************\n");
	printf("邻接矩阵的遍历:\n");
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			printf("%d  ", G.arc[i][j]);
			if (G.arc[i][j] != 0)
				out_deg[i]++;
			if (G.arc[j][i] != 0)
				in_deg[i]++;
		}
		printf("\n");
	}
	printf("*************************\n");
}

void Print_in_out_deg(MGraph G)
{
	printf("\n*************************\n");
	printf("各顶点的度的遍历:\n");
	for (int i = 0; i < G.vexnum; i++) {
		printf("\n第%d条边的入度: %d 与出度: %d\n", i + 1, in_deg[i], out_deg[i]);
	}
	printf("*************************\n");
}

void DFS(MGraph G, int v)
{
	visit[v] = 1;
	printf("%d  ", G.vertices[v]);
	for (int i = 0; i < G.vexnum; i++) {
		if (G.arc[v][i] != 0 && visit[i] == 0)
			DFS(G, i);
	}
}

void DFST(MGraph G)
{
	printf("DFS的遍历:");
	for (int i = 0; i < G.vexnum; i++) {
		if (!visit[i])
			DFS(G, i);
	}
}

int main()
{
	MGraph G;
	QUEUE Q;
	init_queue(&Q);
	CreatMGraph(&G);
	PrintMGraph(G);
	DFST(G);
	BFST(G, &Q);
	Print_in_out_deg(G);
	return 0;
}

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

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

相关文章

将朴素矩阵乘法在共享内存中分块,每个线程只计算结果矩阵中的单个元素

kenel的block中的每个线程用于计算共享内存中矩阵Pd中的一个元素Pd_(i&#xff0c;j)&#xff0c;每个线程都读取Md的一行和Nd的一列。Pd_(0&#xff0c;0)和Pd_(1,0)两个结果是由两个线程完成的。这里一开始只有Pd被加载进共享内存&#xff0c;Md和Nd还在全局内存中&#xff1…

嵌入式软件测试方法-质量模型

软件测试评估质量的时候用到的很多测试度量项 质量大师朱兰提出了“质量管理三部曲”&#xff0c;来对企业质量进行管理。 第一部曲&#xff1a;质量策划&#xff0c;致力于制定质量目标并规定必要的运行过程、准备相关资源以实现质量目标。 第二部曲&#xff1a;质量控制&am…

【java】【经验】java: 错误: 不支持发行版本 6

前言&#xff1a;配置过maven之后&#xff0c;发现原来的一些项目运行提示java: 错误: 不支持发行版本 6或者java: 错误: 不支持发行版本 5&#xff0c;主要原因&#xff1a;是因为项目使用的Java版本和安装的Java版本不符合 目录 1 设置项目java版本 2 设置模块版本 3 set…

马尔可夫链的性质和例子

马尔可夫链的重要性质以及两个例题如下&#xff1a; 注意&#xff1a; 例5中有几个地方需要注意&#xff1a; &#xff08;1&#xff09;为什么 P 11 P 22 p q ( 1 − p ) ( 1 − q ) &#xff0c;而 P 33 p q ( 1 − p ) P_{11} P_{22} pq (1-p)(1-q)&#xff0c;而P…

低代码开发平台:无限潜力,适用于各类应用程序开发!

随着技术的不断进步和市场需求的变化&#xff0c;低代码开发平台成为了构建应用程序的一种热门选择。低代码开发平台通过简化应用程序开发过程&#xff0c;降低了编程门槛&#xff0c;使非技术人员也能够快速构建功能强大的应用程序。不过&#xff0c;低代码开发平台究竟可以开…

[vue-element-admin]下载与安装

一、环境搭建 1 nodejs 源码地址 sudo apt install build-essential # 内含gcc g make等全家桶git clone git://github.com/nodejs/node.git # 下载源码 cd node sudo ./config sudo make && make install # 编译 node -v # 查看是否编译成功二、遇见的问题 问题…

清风数学建模——插值算法

插值法 文章目录 插值法作用定义概念一维插值问题一维插值多项式原理定理 拉格朗日插值法和牛顿插值法埃尔米特插值分段线性插值分段三次埃尔米特插值法代码三次样条插值及其代码例子n维数据的插值&#xff08;了解&#xff09; 作用 数模比赛中&#xff0c;常常需要根据已知的…

QT笔记——QT自定义事件

我们有时候想发送自定义事件 1&#xff1a;创建自定义事件&#xff0c;首先我们需要知道它的条件 1&#xff1a;自定义事件需要继承QEvent 2&#xff1a;事件的类型需要在 QEvent::User 和 QEvent::MaxUser 范围之间&#xff0c;在QEvent::User之前 是预留给系统的事件 3&#…

[ubuntu]创建root权限的用户

一、创建新用户 1、创建新用户 sudo useradd -r -m -s /bin/bash 用户名 # -r&#xff1a;建立系统账号 -m&#xff1a;自动建立用户的登入目录 -s&#xff1a;指定用户登入后所使用的shell2、手动为用户设置密码 passwd 用户名 二、为用户增加root权限 1、添加写权限 ch…

适配器模式:将不兼容的接口转换为可兼容的接口

适配器模式&#xff1a;将不兼容的接口转换为可兼容的接口 什么是适配器模式&#xff1f; 适配器模式是一种结构型设计模式&#xff0c;用于将一个类的接口转换为客户端所期望的另一个接口。它允许不兼容的类能够合作&#xff0c;使得原本由于接口不匹配而无法工作的类能够一…

1.Fay-UE5数字人工程导入(UE数字人系统教程)

Fay-UE5数字人工程导入 1、工程下载&#xff1a;xszyou/fay-ue5: 可对接fay数字人的ue5工程 (github.com) 2、ue5下载安装&#xff1a;Unreal Engine 5 3、ue5插件安装 依次安装以下几个插件 4、双击运行工程 5、切换中文 6、检查插件已启用 7、测试运行

一文看懂intel处理器型号

cpu型号命名 cpu 后缀 外形/功能类型/细分市场后缀优化/设计台式机K高性能&#xff0c;未锁频Φ需要独立显卡S特别版T功耗优化生活方式X/XE最高性能&#xff0c;未锁频移动设备&#xff08;笔记本电脑 2、2 合 1 电脑&#xff09;HX最高性能&#xff0c;所有 SKU 未锁频HK高性…

Python源码:使用Tkinter写一个诗词答题软件

废话不多&#xff0c;直接上源码 # 导入用到的库 import tkinter from tkinter import * from tkinter.messagebox import * import random# 准备一个诗词题库列表 shici_list [(词苑千载&#xff0c;群芳竞秀&#xff0c;盛开一枝女儿花"说的是哪位历史上的哪位才女&am…

陀螺玩具跨境电商亚马逊CPC认证

陀螺指的是绕一个支点高速转动的刚体。陀螺是中国民间最早的娱乐工具之一.形状上半部分为圆形&#xff0c;下方尖锐。从前多用木头制成&#xff0c;现代多为塑料或铁制。玩时可用绳子缠绕&#xff0c;用力抽绳&#xff0c;使直立旋转。或利用发条的弹力旋转。传统古陀螺大致是木…

移动端自动化测试实战

UI自动化测试的价值 1、提升回归测试的效率 2、可以进行兼容性测试 UI 自动化测试应用场景 • 冒烟测试自动化&#xff1a;提测之前自动断言提测质量&#xff0c;提供准入参考。 • 功能测试自动化&#xff1a;辅助 QA 与测试工程师的快速验证。 • 验收测试自动化&#xf…

大模型AI人才培养研习会,上海、武汉站同期招募!

伴随预训练大语言模型技术引发的产业变革&#xff0c;市场对AI人才需求也同样发生着深刻变化&#xff0c;教育迎来了新的机遇与挑战。由中国自动化学会主办&#xff0c;百度公司联合知名高校承办的大模型AI人才培养研习会&#xff0c;首场将于8月19日在武汉、上海双城同期举办&…

python安装xgboost报错

ERROR: Could not find a version that satisfies the requirement xgboost (from versions: none) ERROR: No matching distribution found for xgboost 解决办法&#xff1a; 换成国内的pip源 pip install xgboost -i http://pypi.doubanio.com/simple/ --trusted-host py …

python3学习--使用pandas 数据透视表分析数据--入门示例

什么是透视表&#xff1f; 透视表是一种可以对数据动态排布并且分类汇总的表格格式&#xff0c;可以以多种方式和视角查看数据特征 Pandas库提供了一个名为pivot_table的函数&#xff0c;它将一个特性的值汇总在一个整洁的二维表中。 使用示例 pivot_table函数说明 pandas.…

没有硬核技术,怎么抓得住元宇宙的风口?

自 2021 年起&#xff0c;Web 3.0 与元宇宙逐步成为全球科技界的热门概念。Web 3.0 是技术发展方向的未来&#xff0c;元宇宙是应用场景和生活方式的未来&#xff0c;二者之间是相辅相成、一体两面的依存关系。科技巨头如 Meta、谷歌、苹果、华为、腾讯、OPPO 等均已在积极布局…

7.3 详解NiN模型--首次使用多层感知机(1x1卷积核)替换掉全连接层的模型

一.前提知识 多层感知机&#xff1a;由一个输入层&#xff0c;一个或多个隐藏层和一个输出层组成。&#xff08;至少有一个隐藏层&#xff0c;即至少3层&#xff09; 全连接层&#xff1a;是MLP的一种特殊情况&#xff0c;每个节点都与前一层的所有节点连接&#xff0c;全连接…