【数据结构C++】最小堆实现链式Huffman树

最近在学习Huffman树和Huffman编码,最近学习效率下降严重,两天才看懂写出来。
在写本程序的时候,甚至犯了很多低级错误,例如重复包含了头文件……
思路:
1、创建哈夫曼树需要的最小堆;
2、若给与n个带权值节点需要组成哈夫曼树,那么最小堆需要的节点数为2*n-1;
3、将所有给予权值存放入新建节点并插入最小堆;
4、创建哈夫曼树,每次取出两个最小权值节点;创建一个新节点,权值为两节点权值之和,左右儿子为两节点;
5、再将这个新节点插入最小堆中;
6、重复4、5两步骤n-1次,得到哈夫曼树。

具体代码实现如下:
最小堆.h文件:


typedef struct HuffmanTreeNode {
	int weight;
	struct HuffmanTreeNode* Left;
	struct HuffmanTreeNode* Right;
}HTNode;

class MinHeap {
public:

	//有参构造函数,参数为堆容量
	MinHeap(int max);

	//析构函数
	~MinHeap();

	//1、判断是否为空
	bool IsEmpty();

	//2、判断是否已满
	bool IsFull();

	//3、插入元素
	bool Insert(HTNode* x);

	//4、删除最小元素
	HTNode* DeleteMin();

	//打印测试
	void PrintHeap();
private:
	int HeapSize; //堆的大小
	HTNode** Heap; //创建堆数组
	int HeapCapacity;  //堆容量

	HTNode* MinData;//0位置填充值,也用来删除提醒是否成功
};

最小堆.cpp文件:

MinHeap::MinHeap(int max) {
	//创建0位置填充值
	this->MinData = new HTNode();
	this->MinData->weight = -1000;
	this->MinData->Right = this->MinData->Right = NULL;

	this->HeapCapacity = max;
	this->Heap = new HTNode*[this->HeapCapacity + 1];
	this->HeapSize = 0;

	this->Heap[0] = this->MinData; 
}

//析构函数
MinHeap::~MinHeap() {
	delete[] Heap;
}

//1、判断是否为空
bool MinHeap::IsEmpty() {
	if (this->HeapSize == 0) return true;
	return false;
}

//2、判断是否已满
bool MinHeap::IsFull() {
	if (this->HeapSize == this->HeapCapacity) return true;
	return false;
}

//3、插入元素
bool MinHeap::Insert(HTNode* x) {
	if (IsFull()) return false;

	//定义循环变量i,参与上滤,找到合适位置
	int i = ++this->HeapSize;

	//如果位置不合适,就把父节点元素换下来,直到找到合适位置i
	for (; x->weight < this->Heap[i / 2]->weight; i = i / 2) {
		this->Heap[i] = this->Heap[i / 2];
	}
	this->Heap[i] = x;
	return true;
}

//4、删除最小元素
HTNode* MinHeap::DeleteMin() {
	if (IsEmpty()) return this->MinData;

	HTNode* min = this->Heap[1];
	//将最后一个元素拿到,再将堆大小减一,逻辑删除
	HTNode* temp = this->Heap[this->HeapSize--];
	
	int i = 1;
	int child;
	for (; i <= this->HeapSize / 2; i = child) {

		//先找到左子节点
		child = 2 * i;
		
		//找到两个子节点中最小的
		if (child != this->HeapSize && this->Heap[i * 2]->weight > this->Heap[i * 2 + 1]->weight)
			child++;

		if (temp->weight > this->Heap[child]->weight)
			this->Heap[i] = this->Heap[child];
		else break;
	}
	//找到合适位置,赋值
	this->Heap[i] = temp;
	return min;
}

//打印测试
void MinHeap::PrintHeap() {
	for (int i = 1; i <= this->HeapSize; i++) {
		cout << this->Heap[i]->weight << " ";
	}
	cout << endl;
}

Huffman树.h文件:

class HuffmanTree {
public:
	//构造函数,参数权值数组和数组元素个数
	HuffmanTree(int w[], int n);

	//获取根节点
	HTNode* GetRoot();
private:
	HTNode* Root;
};

Huffman树.cpp文件:

//构造函数,参数权值数组和数组元素个数
HuffmanTree::HuffmanTree(int w[], int n) {
	//创建最小堆
	MinHeap mh(2 * n - 1);
	for (int i = 0; i < n; i++){
		HTNode* temp = new HTNode();
		temp->weight = w[i];
		temp->Right = temp->Left = NULL;
		mh.Insert(temp);
	}
	//建Huffman树
	for (int i = 0; i < n - 1; i++) {
		HTNode* node1 = mh.DeleteMin();
		HTNode* node2 = mh.DeleteMin();
		HTNode* newNode = new HTNode();
		newNode->weight = node1->weight + node2->weight;
		newNode->Left = node1; newNode->Right = node2;

		mh.Insert(newNode);
	}
	this->Root = mh.DeleteMin();
}

//获取根节点
HTNode* HuffmanTree::GetRoot() {
	return this->Root;
}

测试代码:

int main() {
	int w[] = { 1,2,3,4,5 };
	HuffmanTree ht(w, 5);
	return 0;
}

调试可看出结果与下图一致。
在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值