您的位置:首页 > 编程语言 > C语言/C++

简单的C语言赫夫曼树实现代码

2014-10-05 11:08 411 查看
结果:



#include <stdio.h>

#include <MALLOC.H>

#include <ASSERT.H>

#include <STDLIB.H>

#define NODEMAXSIZE 30

typedef int ElemType;

typedef struct Node{

struct Node *left,*rigth,*parent;

ElemType e;

int weight;

}HfmNode;

struct HFM{

HfmNode *nodeArr[NODEMAXSIZE];

int nodeNum;

};

//获取一个节点

HfmNode* getNode()

{

HfmNode *temp;

temp = (HfmNode *)malloc(sizeof(HfmNode));

while(!temp)

{

temp = (HfmNode *)malloc(sizeof(HfmNode));

}

temp->left=temp->rigth=temp->parent = NULL;

temp->weight = 0 ;

return temp;

}

//增加节点

void addNode(HFM *hfm,ElemType e,int weight)

{

assert(hfm->nodeNum < NODEMAXSIZE);

HfmNode *temp;

temp = getNode();

temp->e = e;

temp->weight = weight;

hfm->nodeArr[hfm->nodeNum] = temp;

hfm->nodeNum++;

}

//初始化

void initHfmTree(HFM *hfm,int *elemArr,int length)

{

assert(hfm != NULL);

int i=0;

hfm->nodeNum = 0;

while (i<length)

{

addNode(hfm,i,elemArr[i++]);

}

}

//建立哈夫曼树

void establishHfmTree(HFM *hfm)

{

assert(hfm != NULL);

HfmNode *lchild,*rchild,*partent;

int untreatedNode;//未处理的结点

int tempWeight;

int i;

untreatedNode = hfm->nodeNum;

while(untreatedNode>1)

{

tempWeight = 100000;

i=0;

lchild = rchild = NULL;

while(i<hfm->nodeNum)

{

if (hfm->nodeArr[i]->parent == NULL && tempWeight >= hfm->nodeArr[i]->weight)

{

lchild = hfm->nodeArr[i];

tempWeight = hfm->nodeArr[i]->weight;

}

++i;

}

tempWeight = 100000;

i=0;

while(i<hfm->nodeNum)

{

if (hfm->nodeArr[i]->parent == NULL &&

tempWeight >= hfm->nodeArr[i]->weight && hfm->nodeArr[i] != lchild)

{

rchild = hfm->nodeArr[i];

tempWeight = hfm->nodeArr[i]->weight;

}

++i;

}

partent = getNode();

partent->e = hfm->nodeNum;

partent->left = lchild;

partent->rigth = rchild;

if(lchild != NULL)

{

lchild->parent = partent;

}

if(rchild != NULL)

{

rchild->parent = partent;

}

partent->weight = lchild->weight + rchild->weight;

hfm->nodeArr[hfm->nodeNum] = partent;

hfm->nodeNum++;

--untreatedNode;

}

}

//打印编码

void printCode(int *encode,int encodeLength)

{

int i=0;

while(i<encodeLength)

{

printf("%d",encode[i++]);

}

printf("\n");

}

//获取编码

void getEncode(HfmNode *hfmNode,int *encode,int encodeLength,

void (*op)(int *encode,int encodeLength))

{

if(hfmNode->left == NULL && hfmNode->rigth == NULL)

{

printf("字母:%d\t 权值:%d \t编码:",hfmNode->e,hfmNode->weight);

op(encode,encodeLength);

return ;

}

if(hfmNode->left != NULL)

{

encode[encodeLength] = 0;

getEncode(hfmNode->left,encode,encodeLength+1,op);

}

if(hfmNode->rigth != NULL)

{

encode[encodeLength] = 1;

getEncode(hfmNode->rigth,encode,encodeLength+1,op);

}

}

//销毁哈夫曼树

void destoryHfmTree(HFM *hfm)

{

int i=0;

while (i<hfm->nodeNum)

{

free(hfm->nodeArr[i++]);

}

}

int main(void)

{

//在此,数组的下标就是要编码的字母,数组的内容就是权值

//如果需要转换成其他字符,只需要对数组下标和字符进行一个映射即可

//如果需要帮助:lwj4616#foxmail.com

ElemType elemArr[]={4,3,96,2,53,22,66,12,43,2};

int length = sizeof(elemArr)/sizeof(elemArr[0]);

int encode[30];

HFM hfm;

printf("\n\n------------赫夫曼树------------\n\n");

initHfmTree(&hfm,elemArr,length);

establishHfmTree(&hfm);

getEncode(hfm.nodeArr[hfm.nodeNum-1],encode,0,&printCode);

destoryHfmTree(&hfm);

printf("\n树已销毁...\n");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: