哈夫曼树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 5 //叶子节点数
#define M 2*N-1 //哈夫曼树结点
#define MAX 10000
typedef char TElemType;
//三叉链表
typedef struct {
unsigned int weight;
int parent;
int lchild;
int rchild;
} HTNode;
typedef HTNode HuffmanTree[M+1];
typedef char * HuffmanCode[N+1];//存储每个字符的哈夫曼编码表
void select(HuffmanTree HT, int k, int &s1, int &s2);
//构造哈夫曼树
void createHuffmanTree(HuffmanTree &HT, int *w, int n) {
if(n <= 1)
return;
for(int i = 1; i <= n; i++) {
HT[i].weight = w[i];
HT[i].lchild = 0;
HT[i].parent = 0;
HT[i].rchild = 0;
}
for(int i=1; i <=M; i++) {
HT[i].weight = 0;
HT[i].lchild = 0;
HT[i].parent = 0;
HT[i].rchild = 0;
}
for(int i = n+1; i <= M; i++) {
int s1, s2;
select(HT, i-1, s1, s2);//选择parent为0的且权值最小的2结点
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void select(HuffmanTree HT, int k, int &s1, int &s2) {
unsigned int tmp = MAX, tmpi = 0;
for(int i = 1; i <= k; i++) {
if(!HT[i].parent) {
if(tmp > HT[i].weight) {
tmp = HT[i].weight;
tmpi = i;
}
}
}
s1 = tmpi;
tmp = MAX;
tmpi = 0;
for(int i = 1; i <= k; i++) {
if((!HT[i].parent) && i!=s1) { //parent为0
if(tmp > HT[i].weight) {
tmp = HT[i].weight;
tmpi = i;
}
}
}
s2 = tmpi;
}
//求解哈夫曼编码
void encodingHuffmanCode(HuffmanTree HT, HuffmanCode &HC) {
char tmp[N];
tmp[N-1] = '\0';
int start, c, f;
for(int i = 1; i <= N; i++) {
start = N-1;
c = i;
f = HT[i].parent;
while(f) {
if(HT[f].lchild == c) {
tmp[--start] = '0';
} else {
tmp[--start] = '1';
}
c = f;
f = HT[f].parent;
}
HC[i] = (char *)malloc((N-start)*sizeof(char));
strcpy(HC[i], &tmp[start]);
}
}
//打印哈夫曼编码表
void printHuffmanCoding(HuffmanCode HC, char ch[]) {
printf("\n");
for(int i = 1; i <= N; i++) {
printf("%c:%s\n", ch[i], HC[i]);
}
printf("\n");
}
int main() {
HuffmanTree HT;
TElemType ch[N+1];
int w[N+1];
printf("请输入%d个字符以及该字符对应的权值(如:a,20):\n", N);
for(int i = 1; i <= N; i++) {
scanf("%c,%d", &ch[i], &w[i]);
getchar();
}
createHuffmanTree(HT, w , N);
HuffmanCode HC;
encodingHuffmanCode(HT, HC);//为每个字符求解哈夫曼编码
printHuffmanCoding(HC, ch);
return 0;
}
//a,20 b,30 c,40 d,10 e,60
中序线索二叉树
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef enum {Link, Thread} PointerTag;
//PointerTag为标志,Link=0代表指针,Thread=1代表线索
typedef struct BiThrNode {
char data;
struct BiThrNode *lchild, *rchild;
PointerTag ltag;
PointerTag rtag;
} BiThrNode, *BiThrTree;
BiThrTree pre;
void CreateBiThrTree( BiThrTree *T ) {
char c;
scanf("%c", &c);
if( '@' == c ) {
*T = NULL;
}
else {
*T = (BiThrNode *)malloc(sizeof(BiThrNode));
(*T)->data = c;
(*T)->ltag = Link;
(*T)->rtag = Link;
CreateBiThrTree(&(*T)->lchild);
CreateBiThrTree(&(*T)->rchild);
}
}
// 中序遍历线索化
void InThreading(BiThrTree T) {
if( T ) {
InThreading( T->lchild ); // 递归左孩子线索化
if( !T->lchild ) { // 如果该结点没有左孩子,设置ltag为Thread,并把lchild指向刚刚访问的结点。
T->ltag = Thread;
T->lchild = pre;
}
if( !pre->rchild ) {
pre->rtag = Thread;
pre->rchild = T;
}
pre = T;
InThreading( T->rchild ); // 递归右孩子线索化
}
}
void InOrderThreading( BiThrTree *p, BiThrTree T ) {
*p = (BiThrTree)malloc(sizeof(BiThrNode));
(*p)->ltag = Link;
(*p)->rtag = Thread;
(*p)->rchild = *p;
if( !T ) {
(*p)->lchild = *p;
} else {
(*p)->lchild = T;
pre = *p;
InThreading(T);
pre->rchild = *p;
pre->rtag = Thread;
}
}
void visit( char c ) {
printf("%c", c);
}
// 中序遍历二叉树
void InOrderTraverse( BiThrTree T ) {
BiThrTree p;
p = T->lchild;
while( p != T ) {
while( p->ltag == Link ) {
p = p->lchild;
}
visit(p->data);
while( p->rtag == Thread && p->rchild != T ) {
p = p->rchild;
visit(p->data);
}
p = p->rchild;
}
}
int main() {
BiThrTree P, T = NULL;
CreateBiThrTree( &T );
InOrderThreading( &P, T );
printf("中序遍历输出结果为: ");
InOrderTraverse( P );
printf("\n");
return 0;
}
//ABC@@DE@G@@F@@@