自己对于优先队列构造赫夫曼殊的想法和考虑
先构造一个队列来储存自己想要的权值 然后将队列中的值一一相加 在放入树中
例如 1 2 4 5 -> 3 4 5 ->* 5 7*-> 12 队列中的值会慢慢变成这样
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct WEIGHT
{
int weight; //权重
struct WEIGHT *next;
}Weight;
typedef struct QUEUE
{
Weight *node;
int count; //记录长度
}Queue;
typedef struct TREE //动态分配数组存储赫夫曼树
{
int weight; //权值
struct TREE *lchild, *rchild;
int count; //记录小树的个数
}Htree;
typedef char **Hcode; //动态分配数组存储赫夫曼编码表
Queue *Q;
Htree *H = (Htree *)malloc(sizeof(Htree));
void NullQueue(Queue *&Q) //初始化优先队列
{
Q = (Queue *)malloc(sizeof(Queue));
Q->node = (Weight *)malloc(sizeof(Weight));
Q->count = 0;
Q->node->next = NULL;
}
void AddQueue(Queue *&Q, Weight *&W) //添加 从小到大排序
{
Weight *T = Q->node;
int n = 0; //用来检验是不是到了队列末尾
while (T->next != NULL)
{
if (T->next->weight > W->weight) //判断加入的值是否小于
{
Weight *P = (Weight *)malloc(sizeof(Weight));
P = T->next;
W->next = P;
T->next = W;
n++;
break;
}
T = T->next;
}
if (n == 0)
T->next = W;
Q->count++;
}
int GetQueue(Queue *&Q) //删除并返回元素
{
Weight *P = Q->node->next;
Weight *T = Q->node;
T->next = P->next;
int n = P->weight;
Q->count--;
free(P);
return n;
}
void ReadQueue(Queue *&Q) //遍历队列
{
Weight *T = Q->node;
while (T->next != NULL)
{
printf("%d ", T->next->weight);
T = T->next;
}
}
void AddHtree(Htree *&H, int x, int y, int sum) //构造赫夫曼树 y为合并后的
{
if (H->count == 0) //建立第一棵
{
H->weight = sum;
if (x > y)
{
H->lchild = (Htree *)malloc(sizeof(Htree));
H->rchild = (Htree *)malloc(sizeof(Htree));
H->lchild->weight = y;
H->lchild->lchild = NULL;
H->lchild->rchild = NULL;
H->rchild->weight = x;
H->rchild->lchild = NULL;
H->rchild->rchild = NULL;
}
else
{
H->lchild = (Htree *)malloc(sizeof(Htree));
H->rchild = (Htree *)malloc(sizeof(Htree));
H->lchild->weight = x;
H->lchild->lchild = NULL;
H->lchild->rchild = NULL;
H->rchild->weight = y;
H->rchild->lchild = NULL;
H->rchild->rchild = NULL;
}
}
else
{
Htree *P = (Htree *)malloc(sizeof(Htree));
P->count = H->count;
P->weight = sum;
if (y > x) //判断2个权的大小
{
P->lchild = (Htree *)malloc(sizeof(Htree));
P->rchild = (Htree *)malloc(sizeof(Htree));
if (H->weight == x) //判断子树和先加入的树
{
P->rchild->weight = y;
P->lchild = H; //连接之前建立的树
P->rchild->lchild = NULL;
P->rchild->rchild = NULL;
}
else //判断子树和先加入的树
{
P->lchild->weight = x;
P->rchild = H; //连接之前建立的树
P->lchild->lchild = NULL;
P->lchild->rchild = NULL;
}
}
else
{
P->lchild = (Htree *)malloc(sizeof(Htree));
P->rchild = (Htree *)malloc(sizeof(Htree));
if (H->weight == x)
{
P->rchild->weight = y;
P->lchild = H; //连接之前建立的树
P->rchild->lchild = NULL;
P->rchild->rchild = NULL;
}
else
{
P->lchild->weight = x;
P->rchild = H; //连接之前建立的树
P->lchild->lchild = NULL;
P->lchild->rchild = NULL;
}
}
H = P;
}
H->count++;
}
void ReadHtree(Htree *&H) //先序遍历树
{
if (H)
{
printf("%d ", H->weight);
ReadHtree(H->lchild);
ReadHtree(H->rchild);
}
}
int main()
{
H->count = 0;
NullQueue(Q);
int n = 4;
while (n--)
{
Weight *W = (Weight *)malloc(sizeof(Weight));
W->next = NULL;
scanf("%d", &W->weight);
getchar();
AddQueue(Q, W);
}
ReadQueue(Q);
printf("\n");
//合并2个权
while (Q->count != 1)
{
int x = GetQueue(Q); //第一个的权值
int y = GetQueue(Q); //第二个的权值
Weight *W = (Weight *)malloc(sizeof(Weight));
W->weight = x + y;
W->next = NULL;
AddQueue(Q, W);
AddHtree(H, x, y, x + y);
ReadHtree(H);
printf("\n");
}
}