百度也看了很多博客都没解决
主要代码如下
typedef struct HTNode {
int weight;
char c;//存这个字符,单个字符,符号都是叶子节点
int code;
HTNode *lchild, rchild;
}HuffmanTree;
/
数据字典,顺序线性表
*/
typedef struct {
int *weight;
char c;//字符数组
int length;//存储数据的长度
int listsize;
HuffmanTree t;//二维指针,存放指针的指针数组,因为节点是指针,所以需要存放指针的数组
}DATA;
DATA D;
HuffmanTree T = (HuffmanTree)malloc(sizeof(HTNode));//根
/
字典初始化
*/
void InitList(DATA &D) {
D.weight = (int *)malloc(DEFAULTSIZE * sizeof(int));
D.c = (char *)malloc(DEFAULTSIZE * sizeof(char));
D.t = (HuffmanTree *)malloc(DEFAULTSIZE * sizeof(HuffmanTree));
if (!D.weight || !D.c || !D.t)
return;
D.length = 0;
D.listsize = DEFAULTSIZE;
D.t = null;
for (int i = 0; i < D.listsize; i++) {
D.t[i] = (HuffmanTree)malloc(sizeof(HTNode));//[^2]错误在这,引发了异常: 写入访问权限冲突。
D.t 是 0x1110112。
D.t[i]->lchild = NULL;
D.t[i]->rchild = NULL;
D.t[i]->weight = 0;
D.t[i]->c = NULL;
}
}
还在调试的源代码,不确定还有没有其他错误
#include
#include
#define null NULL
#define DEFAULTSIZE 50
#define ADDSIZE 10
using namespace std;
typedef struct HTNode {
int weight;
char c;//存这个字符,单个字符,符号都是叶子节点
int code;
HTNode *lchild, rchild;
}HuffmanTree;
/
数据字典,顺序线性表
*/
typedef struct {
int *weight;
char c;//字符数组
int length;//存储数据的长度
int listsize;
HuffmanTree t;//二维指针,存放指针的指针数组,因为节点是指针,所以需要存放指针的数组
}DATA;
DATA D;
HuffmanTree T = (HuffmanTree)malloc(sizeof(HTNode));//根
/
字典初始化
*/
void InitList(DATA &D) {
D.weight = (int *)malloc(DEFAULTSIZE * sizeof(int));
D.c = (char *)malloc(DEFAULTSIZE * sizeof(char));
D.t = (HuffmanTree *)malloc(DEFAULTSIZE * sizeof(HuffmanTree));
if (!D.weight || !D.c || !D.t)
return;
D.length = 0;
D.listsize = DEFAULTSIZE;
D.t = null;
for (int i = 0; i < D.listsize; i++) {
D.t[i] = (HuffmanTree)malloc(sizeof(HTNode));
D.t[i]->lchild = NULL;
D.t[i]->rchild = NULL;
D.t[i]->weight = 0;
D.t[i]->c = NULL;
}
}
void deleteChar(DATA &D) {
D.c[D.length - 1] = null;
D.weight[D.length - 1] = 0;
D.c[D.length - 2] = null;
D.weight[D.length - 2] = 0;
D.length -= 2;
}
void Initdata(DATA &D,char c) {
if (D.length + 1 >= D.listsize) {
D.weight = (int *)realloc(D.weight, (D.listsize + ADDSIZE) * sizeof(int));
D.c = (char *)realloc(D.c, (D.listsize + ADDSIZE) * sizeof(char));
D.t = (HuffmanTree *)realloc(D.t, (D.listsize + ADDSIZE) * sizeof(HTNode *));
D.listsize += ADDSIZE;
}
D.weight[D.length] = 1;//初始化为1
D.c[D.length] = c;
D.length++;
//order(D);//重新 排序
}
/**
根据weight排序,对应位置的字符也要改变位置,大的放前面
/
void order(DATA &D) {
for (int j = D.length; j > 0; j–) {
int min = 0;
HuffmanTree a;
for (int i = 0; i < j; i++) {
if (D.weight[i] < D.weight[min]) {
D.weight[i] += D.weight[min];
D.weight[min] = D.weight[i] - D.weight[min];
D.weight[i] = D.weight[i] - D.weight[min];
D.c[i] += D.c[min];
D.c[min] = D.c[i] - D.c[min];
D.c[i] = D.c[i] - D.c[min];
a = D.t[i];
D.t[i] = D.t[min];
D.t[min] = a;
min = i;
}
}
}
}
/*
两个最小的构造树,权重之和还有参加排序,根节点
*/
void addNode(DATA &D, int w) {
if (D.length + 1 >= D.listsize) {
D.weight = (int *)realloc(D.weight, (D.listsize + ADDSIZE) * sizeof(int));
D.c = (char *)realloc(D.c, (D.listsize + ADDSIZE) * sizeof(char));
D.t = (HuffmanTree )realloc(D.t, (D.listsize + ADDSIZE) * sizeof(HTNode ));
D.listsize += ADDSIZE;
}
D.weight[D.length] = w;
D.c[D.length] = NULL;
D.length++;
order(D);
}
/
计算出现的概率
*/
int check(DATA D, char ch) {//不是指针可以直接用==判断
for (int i = 0;i <= D.length;i++) {
if (D.c[i] == ch)
return i;
}
return -1;
}
int countWeight(istream& input,DATA &D) {//文件中的字符出现个数
char ch;
while (input.get(ch)) {
//遍历字典,有则加1,没有则创建
int j = check(D, ch);
if (j != -1) {
D.weight[j]++;
}
else {
Initdata(D, ch);
}
}
return D.length;//字符种类数(叶子节点数)
}
void InitLink(HuffmanTree &N,int w,char ch) {//对节点初始化
if (N) {
N->weight = w;
N->c = ch;
}
}
int createTree(DATA &D,HuffmanTree &T) {//构造赫夫曼树,用递归或者栈?循环,根接点地址赋值给T无论怎么变最终都会到达根
int newadd = 0;//记录非叶子节点的数
while (D.weight[0] != 0) {
int newweight = D.weight[D.length - 1] + D.weight[D.length - 2];
addNode(D, newweight);
newadd++;
HuffmanTree H = (HuffmanTree)malloc(sizeof(HTNode));
H = D.t[D.length];
InitLink(D.t[D.length],newweight,’ ');
T = D.t[D.length];
D.t[D.length]->lchild =D.t[D.length - 1];
D.t[D.length - 1]->code = 0;//左枝为0
//D.t[D.length - 1]->flag = true;
D.t[D.length]->rchild = D.t[D.length - 2];
D.t[D.length - 1]->code = 1;//右1
//D.t[D.length - 1]->flag = true;
InitLink(D.t[D.length - 1],D.weight[D.length - 1],D.c[D.length - 1]);
InitLink(D.t[D.length - 2],D.weight[D.length - 2], D.c[D.length - 2]);
deleteChar(D);
}
return newadd;
}
//bool visit(ostream& output, HuffmanTree T) {
// if (!T->lchild && !T->rchild) {
// output << “符号:” << T->c << “编码:”;
// return true;
// }
// return true;
//}
void showdata(DATA D,int a) {
ofstream output(“result.txt”);
for (int i = 0; i < a; i++) {
output << “符号:” << D.c[i] << “权重:” << D.weight[i];
}
}
void HuffCode(HuffmanTree T,int len,DATA D) {
ofstream output(“result.txt”);
if (T) {
output << “编码:”;
if (T->lchild) {
output << 0;
if (!T->lchild->lchild)
output << “符号:” << T->lchild->c << “\n”;
HuffCode(T->lchild,len,D);
}
if (T->rchild) {
output << 1;
if (!T->rchild->rchild)
output << “符号:” << T->rchild->c << “\n”;
HuffCode(T->rchild, len, D);
}
}
}
int main()
{
InitList(D);
const char* fileName = “G:\数据结构C语言\赫夫曼树对文本文件编码与译码\test.txt”;
fstream obIn(fileName);
if (obIn.is_open()) {
int b = countWeight(obIn, D);
order(D);
int a = createTree(D, T);
int c = a + b;
showdata(D, b);
//HuffCode(T, c, D);
}
else
cout << “open " << fileName << " is fail!” << endl;
return 0;
}