构建一个很简单的赫夫曼树

自己对于优先队列构造赫夫曼殊的想法和考虑
先构造一个队列来储存自己想要的权值 然后将队列中的值一一相加 在放入树中
例如 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");
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值