c语言输出后续字母,输入字母和权值,输出哈夫曼编码,用c语言实现

#include

#include

#include

#define N 20

#define M 2*N-1

typedef struct

//哈夫曼树的类型定义

{

int weight;

int parent;

int LChild;

int RChild;

}HTNode,HuffmanTree[M+1];

typedef char *HuffmanCode[N+1];

void CrtHuffmanTree(HuffmanTree ht,int w[],int n)

//构造哈夫曼树ht[M+1],w[]存放n个权值

{

int i,k,Lnode,Rnode,Min1,Min2,max=0;

int m=2*n-1;

for(i=1;i<=n;i++) //叶子结点初始化

{

ht[i].weight=w[i];

ht[i].parent=0;

ht[i].LChild=0;

ht[i].RChild=0;

}

for(i=n+1;i<=m;i++) //非叶子结点初始化

{

ht[i].weight=0;

ht[i].parent=0;

ht[i].LChild=0;

ht[i].RChild=0;

}

for(i=n+1;i<=m;i++)//建立哈夫曼树

{

Min1=Min2=10000;

Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置

for(k=1;k

{

if(ht[k].parent==0)

{

if(ht[k].weight

{

Min2=Min1;

Rnode=Lnode;

Min1=ht[k].weight;

Lnode=k;

}

else

if(k!=Lnode&&ht[k].weight

{

Min2=ht[k].weight;

Rnode=k;

}

}

}

ht[i].weight=Min1+Min2;

ht[i].LChild=Lnode;ht[i].RChild=Rnode;

ht[Lnode].parent=i;ht[Rnode].parent=i;

}

printf("\n哈夫曼树的终态\n序号\tWeight\tParent\tLChild\tRChild\n");

for(i=1;i<=m;i++)//测试代码

{

printf("%d",i);

printf(" %d",ht[i].weight);

printf(" %d",ht[i].parent);

printf(" %d",ht[i].LChild);

printf(" %d",ht[i].RChild);

printf("\n");

}

printf("\n");

}

void CrtHuffmanCode(HuffmanTree ht,int n)

//从叶子结点到根,逆求每个叶子结点对应的哈夫曼编码,左0右1

{

char *cd;

int i,j,c,p,start;

cd=(char *)malloc(n*sizeof(char));

//分配求当前编码的工作空间

cd[n-1]='\0';//从右向左逐位存放编码,首先存放编码结束符

for(i=1;i<=n;i++)//求n个叶子结点对应的哈夫曼编码

{

start=n-1;//初始化编码起始指针

c=i;p=ht[i].parent;

//从叶子结点开始向上倒推,寻找该叶子结点的父母

while(p!=0)

{

--start;

if(ht[p].LChild==c)

cd[start]='0';//判断是左边还是右边,左分支标0

else

cd[start]='1';//右分支标1

c=p;p=ht[p].parent;//继续向上倒推

}

//hc[i]=(char *)malloc((n-start)*sizeof(char));

//strcpy(hc[i],&cd[start]);

for(j=0;j

{

if(cd[j]=='0'||cd[j]=='1')

printf("%c",cd[j]);

}

printf("\t");

for(j=0;j

{

cd[j]=' ';

}

}

free(cd);

}

void main()

{

HuffmanTree ht1;

// HuffmanCode hc;

char ch[20];

int i,a,w[20];

printf("请输入字符个数(小于20):");

scanf("%d",&a);

printf("请输入字符:");

getchar();

for(i=1;i<=a;i++)//输入字符

ch[i]=getchar();

getchar();

printf("请输入各个字符对应的权值:");

for(i=1;i<=a;i++)//输入各个字符对应的权值

scanf("%d",&w[i]);

CrtHuffmanTree(ht1,w,a);//调用函数构造哈夫曼树

printf("\n\t\t各字符的哈夫曼树编码\n");

printf("\t字符\t");

for(i=1;i<=a;i++)

printf("%c\t",ch[i]);

printf("\n\t权值\t");

for(i=1;i<=a;i++)

printf("%d\t",w[i]);

printf("\n  哈夫曼编码\t");

CrtHuffmanCode(ht1,a);//调用函数输出哈夫曼编码

printf("\n");

}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的C语言实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_TREE_HT 100 //哈夫曼树节点结构体 struct MinHeapNode { char data; unsigned freq; struct MinHeapNode *left, *right; }; //哈夫曼树结构体 struct MinHeap { unsigned size; unsigned capacity; struct MinHeapNode** array; }; //创建一个新的哈夫曼树节点 struct MinHeapNode* newNode(char data, unsigned freq) { struct MinHeapNode* node = (struct MinHeapNode*) malloc(sizeof(struct MinHeapNode)); node->left = node->right = NULL; node->data = data; node->freq = freq; return node; } //创建一个新的哈夫曼树 struct MinHeap* createMinHeap(unsigned capacity) { struct MinHeap* minHeap = (struct MinHeap*) malloc(sizeof(struct MinHeap)); minHeap->size = 0; minHeap->capacity = capacity; minHeap->array = (struct MinHeapNode**) malloc(minHeap->capacity * sizeof(struct MinHeapNode*)); return minHeap; } //交换两个哈夫曼树节点 void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) { struct MinHeapNode* t = *a; *a = *b; *b = t; } //调整哈夫曼树节点的位置 void minHeapify(struct MinHeap* minHeap, int idx) { int smallest = idx; int left = 2 * idx + 1; int right = 2 * idx + 2; if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq) smallest = left; if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq) smallest = right; if (smallest != idx) { swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]); minHeapify(minHeap, smallest); } } //判断哈夫曼树是否只有一个节点 int isSizeOne(struct MinHeap* minHeap) { return (minHeap->size == 1); } //获取哈夫曼树的最小节点 struct MinHeapNode* extractMin(struct MinHeap* minHeap) { struct MinHeapNode* temp = minHeap->array[0]; minHeap->array[0] = minHeap->array[minHeap->size - 1]; --minHeap->size; minHeapify(minHeap, 0); return temp; } //插入一个新的哈夫曼树节点 void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode) { ++minHeap->size; int i = minHeap->size - 1; while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) { minHeap->array[i] = minHeap->array[(i - 1) / 2]; i = (i - 1) / 2; } minHeap->array[i] = minHeapNode; } //构建哈夫曼树 struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) { struct MinHeapNode *left, *right, *top; struct MinHeap* minHeap = createMinHeap(size); for (int i = 0; i < size; ++i) insertMinHeap(minHeap, newNode(data[i], freq[i])); while (!isSizeOne(minHeap)) { left = extractMin(minHeap); right = extractMin(minHeap); top = newNode('$', left->freq + right->freq); top->left = left; top->right = right; insertMinHeap(minHeap, top); } return extractMin(minHeap); } //判断节点是否是叶子节点 int isLeaf(struct MinHeapNode* root) { return !(root->left) && !(root->right); } //打印哈夫曼编码 void printHuffmanCodes(struct MinHeapNode* root, int arr[], int top) { if (root->left) { arr[top] = 0; printHuffmanCodes(root->left, arr, top + 1); } if (root->right) { arr[top] = 1; printHuffmanCodes(root->right, arr, top + 1); } if (isLeaf(root)) { printf("%c: ", root->data); for (int i = 0; i < top; ++i) printf("%d", arr[i]); printf("\n"); } } //哈夫曼编码主函数 void HuffmanCodes(char data[], int freq[], int size) { struct MinHeapNode* root = buildHuffmanTree(data, freq, size); int arr[MAX_TREE_HT], top = 0; printHuffmanCodes(root, arr, top); } //测试 int main() { char data[] = {'a', 'b', 'c', 'd', 'e', 'f'}; int freq[] = {5, 9, 12, 13, 16, 45}; int size = sizeof(data) / sizeof(data[0]); HuffmanCodes(data, freq, size); return 0; } ``` 以上代码实现输入字符和频率,输出哈夫曼编码的功能。你可以根据自己的需求修改输入输出的方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值