哈夫曼编码(补充动态申请二维数组)
声明:图片及内容基于https://www.bilibili.com/video/BV1ke411s7Nk?from=articleDetail
概念
哈夫曼编码代码
void huffmanCoding(element *huffTree,char *huffCode[],int n){
char *temp=new char[n];
temp[n-1]='\0';
int start;
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]);
}
delete temp;
}
完整代码
#include<iostream>
#include<iomanip>
#include<limits.h>
#include<string.h>
using namespace std;
struct element{
int weight;
int lchild,rchild,parent;
};
void select(element *huffTree,int k,int &s1,int &s2);
HuffmanTree(element *huffTree,int *w,int n){
for(int i=0;i<2*n-1;i++){
huffTree[i].parent=-1;
huffTree[i].lchild=-1;
huffTree[i].rchild=-1;
}
for(int i=0;i<n;i++){
huffTree[i].weight=w[i];
}
for(int k=n;k<2*n-1;k++){
int s1,s2;
select(huffTree,k,s1,s2);
huffTree[k].weight=huffTree[s1].weight+huffTree[s2].weight;
huffTree[k].lchild=s1;
huffTree[k].rchild=s2;
huffTree[s1].parent=k;
huffTree[s2].parent=k;
cout << "最小下标:" << s1 << " 次小下标:" << s2 << endl;
}
}
void select(element *huffTree,int k,int &s1,int &s2){
int min1=INT_MAX;
int min2=INT_MAX;
s1=s2=0;
for(int i=0;i<k;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 huffmanCoding(element *huffTree,char *huffCode[],int n){
char *temp=new char[n]; //temp取了可能的最大长度
temp[n-1]='\0';
int start; //是字符串temp的下标
int parent;
for(int i=0;i<n;i++){
start=n-1; //从后往前填写字符串,因为是从叶子节点往根遍历的,需要反着填
int pos=i; //pos指当前结点位置
parent=huffTree[i].parent;
while(parent!=-1){
if(huffTree[parent].lchild==pos){ //左孩子0
temp[--start]='0';
}
else{ //右孩子1
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;
cout<<"请输入"<<n<<"个权值"<<endl;
int *w=new int[n];
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 << setw(2) << huffTree[i].weight << " " << setw(2) << huffTree[i].parent
<< " " << setw(2) << huffTree[i].lchild << " " << setw(2) << huffTree[i].rchild << endl;
}
//char *huffCode[n];
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]; //每个huffCode里的元素都是字符串,及char数组
}
cout<<"delete";
delete []huffCode; //再删除**huffCode
}
输入:
7
9 11 5 7 8 2 3
输出:
最小下标:5 次小下标:6
最小下标:2 次小下标:7
最小下标:3 次小下标:4
最小下标:0 次小下标:8
最小下标:1 次小下标:9
最小下标:10 次小下标:11
打印哈夫曼树的数组内容:
weight parent lchild rchild
9 10 -1 -1
11 11 -1 -1
5 8 -1 -1
7 9 -1 -1
8 9 -1 -1
2 7 -1 -1
3 7 -1 -1
5 8 5 6
10 10 2 7
15 11 3 4
19 12 0 8
26 12 1 9
45 -1 10 11
00
10
010
110
111
0110
0111
动态申请二维数组
#include<iostream>
using namespace std;
int main(){
int n,m;
cout<<"请输入行和列"<<endl;
cin>>n>>m;
int **array=new int*[n];
for(int i=0;i<n;i++){
array[i]=new int[m];
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>array[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<array[i][j]<<" ";
}
cout<<endl;
}
for(int i=0;i<n;i++)
delete [] array[i]; // 每个array里的元素都是数组
delete []array;
return 0;
}