深入理解数据结构——哈夫曼树

2023-11-18

#include <iostream>
#include <string>

using namespace std;

typedef char EType;
利用链表实现:哈夫曼树中的节点结构定义为
//struct HuffmanNode {
//	int weight;//权值
//	EType data;//Node information
//	HuffmanNode* next;//后继节点
//	HuffmanNode* LChird;//zuo孩节点
//	HuffmanNode* RChird;//you
//};


//利用堆实现:哈夫曼树中的节点结构定义为
struct HuffmanNode {
	int weight;//权值
	BinaryTreeNode* root;//指向对应的子树根节点
};
struct BinaryTreeNode {
	int data;
	BinaryTreeNode* LChird;
	BinaryTreeNode* RChird;
};



struct MinHeap {
	HuffmanNode* heap;
	int HeapSize;
	int MaxSize;
};



void CreatMinHeap(MinHeap& H, int n) {
	H.HeapSize = n;
	H.MaxSize = n;
	H.heap = new HuffmanNode[H.HeapSize];
}




//初始化一个非空的最大堆算法

void MinHeapInit(MinHeap& H) {
	//从堆中的数据初始化一个最小堆

	for (int i = H.HeapSize / 2; i >= 1; i--) {
		H.heap[0] = H.heap[i];//将子树根节点的值复制到工作空间heap[0]
		
		int son = 2 * i;

		while (son >= H.HeapSize) {
			//找到左右孩中较小的节点
			//son >= H.HeapSize时,存在右孩子,如果左孩子小于右孩子,son指向右孩子
			if (son > H.HeapSize && (H.heap[son].weight > H.heap[son + 1].weight)) {
				son++;
			}
			//大孩子与工作空间的节点值再比较,工作空间的值较小,找到Heap[0]的目标位置
			if (H.heap[0].weight <= H.heap[son].weight) break;

			H.heap[son / 2] = H.heap[son];//将小孩子上移动到双亲位子
			son *= 2;//son下移一层到上移的节点(小孩子位置)
		}
		H.heap[son / 2] = H.heap[0];//heap[0]存放的到目标位置
	}
}


bool MinHeapInsert(MinHeap& H, HuffmanNode& x) {
	//插入值为x的节点,到最XIAO堆中,maxsize是数组最大的容量

	if (H.HeapSize == H.MaxSize)
		return false;//数据空间已满
	int i = ++H.HeapSize;//i为插入节点后的节点个数

	while (i != 1 && x.weight < H.heap[i / 2].weight) {
		H.heap[i] = H.heap[i / 2];

		i = i / 2;//节点下移
	}

	H.heap[i] = x;
	return true;
}



//最xiao堆中删除堆顶节点,并放入x中算法

bool MinHeapDelete(MinHeap& H, HuffmanNode& x) {

	if (H.HeapSize == 0) return false;
	x = H.heap[1];//最小节点存放到x
	H.heap[0] = H.heap[H.HeapSize--];//最后一个节点放在heap[0],调整堆中元素的个数

	int i = 1, son = 2 * i;

	while (son >= H.HeapSize) {
		//找到左右孩中较小的节点
		//son >= H.HeapSize时,存在右孩子,如果左孩子大于右孩子,son指向右孩子
		if (son > H.HeapSize && (H.heap[son].weight > H.heap[son + 1].weight)) {
			son++;
		}
		//大孩子与工作空间的节点值再比较,工作空间的值较小,找到Heap[0]的目标位置
		if (H.heap[0].weight <= H.heap[son].weight) break;


		H.heap[i] = H.heap[son];//孩子上移
		i = son;		//下移节点指针,继续比较
		son *= 2;//son下移一层到上移的节点(小孩子位置)

	}
	H.heap[i] = H.heap[0];//heap[0]存放的到目标位置
	return true;

}

//堆排序
void HeapSort(MinHeap& H) {
	//利用堆对H.heap[1:n]数组中的数据排序
	HuffmanNode x;
	MinHeapInit(H);

	for (int i = H.HeapSize - 1; i >= 1; i--) {
		MinHeapDelete(H, x);
		H.heap[i + 1] = x;
	}
}

//构造二叉树节点
BinaryTreeNode* MakeNode(EType& x) {
	BinaryTreeNode* ptr;
	ptr = new BinaryTreeNode;
	if (!ptr) return NULL;

	ptr->data = x;
	ptr->LChird = NULL;
	ptr->RChird = NULL;
	return ptr;
}


//构造一个二叉树子树
void MakeBinaryTree(BinaryTreeNode* root,
	BinaryTreeNode* left,
	BinaryTreeNode* right) {
	//链接root,left,right所指向节点的二叉树
	root->LChird = left;
	root->RChird = right;
}


BinaryTreeNode* HuffmanTree(int *w,EType *a,int n) {

	//根据权值构造哈夫曼树,形成哈夫曼树是一个动态链接的二叉树

	BinaryTreeNode* ptr;
	MinHeap H;
	CreatMinHeap(H, n);

	for (int i = 1; i <= n; i++) {
		ptr = MakeNode(a[i]);//产生一个节点,data中存放叶子的值
		H.heap[i].weight = w[i];
		H.heap[i].root = ptr;	//哈夫曼堆节点的链接域指向叶子节点
	}

	H.HeapSize = n;
	MinHeapInit(H);
	HuffmanNode L, R, D;
	for (int i = 1; i < n; i++) {
		ptr = new BinaryTreeNode;  //动态申请一个哈夫曼树节点
		MinHeapDelete(H, L);
		MinHeapDelete(H, R);
		D.weight = L.weight + R.weight;//合并L和R的权值,存放到哈夫曼堆节点D中
		ptr->data = D.weight;//哈夫曼树节点data值是合并节点的权值
		MakeBinaryTree(ptr, L.root, R.root);
		//L,R所指向的子树,作为ptr左右子树生成一个新子树
		//哈夫曼树的节点D的链接域指向新子树的根

		D.root = ptr;
		MinHeapInsert(H, D);
	}
	
	return ptr;

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解数据结构——哈夫曼树 的相关文章

  • 如何使用 C# 以编程方式编辑 Power BI Desktop 文档参数或数据源?

    我有一个在 Power BI Desktop 中内置的报告模板 并保存为 pbix 或 pbit 文件 该模板使用DirectQuery SQL数据库作为数据源 而服务器地址和数据库名称被提取到参数中 还有一个参数包含一个ReportId
  • libtool 在 Ubuntu 13.04 上构建 thrift 0.9.1 时出错

    在 Ubuntu 13 04 上构建 thrift 0 9 1 支持 C C java C perl python 时出现此错误 configure 不带任何选项运行 make 不带任何选项运行 Making all in test mak
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 如何使用 C# 查询远程 MS ACCESS .mdb 数据库

    我正在尝试使用 C 查询 mote MS ACCESS 数据库 mdb 文件 将文件复制到本地计算机时可以成功查询它 我只想远程放置文件 所以我的客户端程序不包含原始数据 static string m path http www xyz
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 在 C++ 代码 gdb 中回溯指针

    我在运行 C 应用程序时遇到段错误 在 gdb 中 它显示我的一个指针位置已损坏 但我在应用程序期间创建了 10 万个这样的对象指针 我怎样才能看到导致崩溃的一个 我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗 谢谢 鲁奇 据我
  • 在 mvc4 中创建通用 mvc 视图

    我以前也提过类似的问题 没有得到答案 如何创建一个通用的 mvc4 视图 该视图可以显示传递给它的模型列表或单个模型 模型可以是个人 组织或团体 无论传递给它的是什么 如果您正在寻找类似的东西 model MyViewModel
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 将日期时间显示为 MM/dd/yyyy HH:mm 格式 C#

    在数据库中 日期时间以 MM dd yyyy HH mm ss 格式存储 但是 我想以 MM dd yyyy HH mm 格式显示日期时间 我通过使用 String Format 进行了尝试 txtCampaignStartDate Tex
  • 如何调用与现有方法同名的扩展方法? [复制]

    这个问题在这里已经有答案了 我有这样的代码 public class TestA public string ColA get set public string ColB get set public string ColC get se
  • 与 Entity Framework Core 2.0 的一对零关系

    我正在使用 C 和 NET Framework 4 7 将 Entity Framework 6 1 3 Code First 库迁移到 Entity Framework Core 我一直在用 Google 搜索 Entity Framew
  • 初始化列表在 VC10 中不起作用

    我在 VC 2010 中编写了这个程序 class class1 public class1 initializer list
  • 使用 IdentityDbContext 和 Code First 自动迁移表位置和架构的实体框架?

    我正在尝试使用 IdentityDbContext 类设置自动迁移更新 并将更改传播到整个数据库的实际 DbContext 在进入代码之前 在使用自动迁移实现 IdentityDbContext 时 我收到此错误 影响迁移历史系统表位置的自

随机推荐