【数据结构】哈夫曼编码

这篇博客探讨了在C++中new操作符在处理内置类型和自定义类型时的不同行为,强调了new为自定义类型分配内存时会调用默认构造函数。此外,文章提到了new用于创建数组时如何进行值初始化,并指出了使用new [ ]分配的内存应当使用delete [ ]来释放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include <limits.h>
#include<cstring>

using namespace std;

struct element{

	int weight;
	int lchild,rchild,parent;
};

void select(element huffTree[],int n, int &s1,int &s2){

	s1 = s2 = 0;
	int min1 = INT_MAX; //min1为最小值,INI_MAX数值为2^31-1
	int min2 = INT_MAX; //min2为次小值
	//找最小值就默认为最大值

	for(int i=0;i<n;i++){
		if(huffTree[i].parent == -1)
		{ //筛选没有父节点的最小值和次小权值的下标
			if(huffTree[i].weight < min1){
				//如果权值比最小值小,更新最小值
				min2 = min1;
				s2 = s1; //次小值是之前的最小值
				min1 = huffTree[i].weight;
				s1 = i; //更新后的最小值
			}else if((huffTree[i].weight >= min1)&& (huffTree[i].weight < min2)){
				//如果权值大于等于最小值,小于次小值,更新次小值
				min2 = huffTree[i].weight;
				s2 = i;
			}else{;}//如果大于次小值,则什么都不做
		}
	}
}

void HuffmanTree(element huffTree[],int w[],int n){

	for(int i=0;i< 2*n-1;i++){ //初始化
		huffTree[i].lchild = -1;
		huffTree[i].rchild = -1;
		huffTree[i].parent = -1;
	}

	for(int i = 0;i < n;i++){
		huffTree[i].weight = w[i];
	}

	for(int k = n;k < 2 * n-1;k++){
		int i1,i2; //下标i1对应的值最小,i2次小
		select(huffTree,k,i1,i2) ;
		huffTree[k].weight = huffTree[i1].weight+huffTree[i2].weight;
		huffTree[i1].parent = k;
		huffTree[i2].parent = k;
		huffTree[k].lchild = i1;
		huffTree[k].rchild = i2;
		cout<<"最小下标:"<<i1 <<"次小下标:"<<i2<<endl;
	}
}

void huffmanCoding(element * huffTree,char * huffCode[],int n){
	char * temp = new char[n];//数组尽可能大,防止后面字符串赋值时溢出
	temp [n-1] = '\0';
	int start; //start是字符串temp的下标
	int parent;
	for(int i=0;i < n;i++){
		start = n - 1;
		//从后往前填写字符串,因为是从叶子节点向根节点遍历
		int pos = i;
		parent = huffTree[i].parent;
		while(parent != -1){
			if(huffTree[parent].lchild == pos){
				temp[--start] = '0';
			}else{
				temp[--start] = '1';
			}
			pos = parent;
			parent = huffTree[parent].parent;
		}
		huffCode[i] = new char[n-start];
		strcpy(huffCode[i],&temp[start]);
		//字符串拷贝,取temp[start]的地址及temp字符串首地址
	}
	delete temp;
}

int main(){
	int n; //节点个数
	cout << "请输入节点个数:"<<endl;
	cin >> n;
	int * w = new int[n];
	cout << "请输入" << n << "个权值" <<endl;
	for(int i=0;i<n;i++){
		cin>>w[i];
	}
	element *huffTree = new element[2 * n - 1];
	HuffmanTree(huffTree, w, n);
	cout << "打印哈夫曼树的数组内容:"<<endl;
	cout << "weight parent lchild rchild" << endl;
	for (int i = 0; i < 2*n-1; i++) {
		cout << huffTree[i].weight << "     \t" << huffTree[i].parent << "     \t" 
		<< huffTree[i].lchild << "     \t" << huffTree[i].rchild << endl;
	}
	
	char **huffCode = new char *[n];
	huffmanCoding(huffTree,huffCode,n);
	cout<<endl;
	for(int i=0;i<n;i++){
		cout << huffCode[i]<< endl;
	}
	
	delete w;
	delete huffTree;
	for(int i=0;i<n;i++){ //删除二维数组,先循环删除每个*huffCode
		cout<<"delete 第"<<i<<"个元素"<<endl;
		delete[] huffCode[i];
		//TODO
	}
	cout<<"delete";
	delete [] huffCode;//再删除**huffCode
	return 0;
}

补充1:

对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()。

new(多个对象)数组
new分配的对象,不管单个对象还是多个对象的分配,都是默认初始化。 但可以对数组进行值初始化,方法就是:在大小之后添加一对空括号。

int *pia = new int [ 10 ];     // 10个未初始化int
int *pia2 = new int [ 10 ](); // 10个值初始化为0的int

补充2:

使用new [ ]申请的内存释放时要用delete [ ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值