C++实现HuffManTree+代码实现

该代码示例展示了如何在C++中使用自定义结构体和优先级队列来构建哈夫曼树。首先定义了节点结构体和权重类型,接着初始化权重数组并创建哈夫曼树。创建过程中,通过优先级队列按权重排序节点,合并最小的两个节点直到只剩一个节点。同时提供了打印哈夫曼树的函数,用于展示树的结构。
摘要由CSDN通过智能技术生成

1.自定义的结构体和重命名的类型

using namespace std;
const int n = 8;
const int m = n * 2;
typedef unsigned int WeightType;
typedef unsigned int NodeType;
typedef struct {
  WeightType wight;
  NodeType parent, leftchild, rightchild;
} HTNode;

typedef HTNode HuffmanTree[m];

struct IndexWeight {
  int index;
  WeightType wh;
  operator WeightType() const { return wh; }
};

我们给了八个叶子结点(根据自己需要给),然后构成哈夫曼树的话一共要2*n(n是叶子结点的个数)。之后我们将权值为int型,即第四行,构成表的时候需要父节点和孩子结点,也为int,之后的结构体是每一个结点的信息。下面就是构造节点数组(类似于二维数组),最后的结构体是我们用来将当前节点和未使用节点做排序,使用C++stl库中的数据结构模板queue。

2.打印表的函数

void PrintHuffmanTree(HuffmanTree hft) {
  for (int i = 0; i < m; ++i) {
    printf("index=%d,weight=%d,parent=%d,lchild=%d,rchild=%d\n", i,
           hft[i].wight, hft[i].parent, hft[i].leftchild, hft[i].rightchild);
  }
  printf("\n");
}

就是一个简单的打印函数,不做赘述。但是如果打印不整齐的话,自己家制表附和%-3d。

3.初始化哈夫曼树

void InitHuffmanTree(HuffmanTree hft, WeightType w[]) {
  memset(hft, 0, sizeof(HuffmanTree));
  for (int i = 0; i < n; i++) {
    hft[i + 1].wight = w[i];
  }
}

即将叶子节点的表初始化出来。

4.哈夫曼树的具体实现函数

void CreateHuffmanTree(HuffmanTree hft) {
  priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight>>
      qu;//将第一行介绍的结构体作为模板传入vector,greater是将权值按照从小到大的顺序入队
  for (int i = 1; i <= n; i++) {
    qu.push(IndexWeight{i, hft[i].wight});
  }//将叶子节点当前节点位置和权值加入到vector内,push函数即入队
  int k = n + 1;//当前加节点的位置
  while (!qu.empty()) {//循环条件必须队不为空
    if (qu.empty())
      break;
    IndexWeight left = qu.top();//获取当前队中最小权值,同样得队不为空
    qu.pop();//当前元素出队
    if (qu.empty()) {
      break;
    }
    IndexWeight right = qu.top();//获取当前队中最小权值,寄此次循环开始是队中第二小的元素,进入条件队不为空
    qu.pop();//元素出队
    hft[k].wight = left.wh + right.wh;//将当前权值更改为第一小和第二小的和
    hft[k].leftchild = left.index;//左孩子为第一小的权值
    hft[k].rightchild = right.index;//右孩子为第二小的权值
    hft[left.index].parent = k;//将左孩子的父节点更改为k+1
    hft[right.index].parent = k;//同上
    qu.push(IndexWeight{k, hft[k].wight});//当前元素入队
    k++;
  }
}

5.完整代码

#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
const int n = 8;
const int m = n * 2;
typedef unsigned int WeightType;
typedef unsigned int NodeType;
typedef struct {
  WeightType wight;
  NodeType parent, leftchild, rightchild;
} HTNode;

typedef HTNode HuffmanTree[m];

struct IndexWeight {
  int index;
  WeightType wh;
  operator WeightType() const { return wh; }
};
void CreateHuffmanTree(HuffmanTree hft) {
  priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight>>
      qu;
  for (int i = 1; i <= n; i++) {
    qu.push(IndexWeight{i, hft[i].wight});
  }
  int k = n + 1;
  while (!qu.empty()) {
    if (qu.empty())
      break;
    IndexWeight left = qu.top();
    qu.pop();
    if (qu.empty()) {
      break;
    }
    IndexWeight right = qu.top();
    qu.pop();
    hft[k].wight = left.wh + right.wh;
    hft[k].leftchild = left.index;
    hft[k].rightchild = right.index;
    hft[left.index].parent = k;
    hft[right.index].parent = k;
    qu.push(IndexWeight{k, hft[k].wight});
    k++;
  }
}

void PrintHuffmanTree(HuffmanTree hft) {
  for (int i = 0; i < m; ++i) {
    printf("index=%d,weight=%d,parent=%d,lchild=%d,rchild=%d\n", i,
           hft[i].wight, hft[i].parent, hft[i].leftchild, hft[i].rightchild);
  }
  printf("\n");
}

void InitHuffmanTree(HuffmanTree hft, WeightType w[]) {
  memset(hft, 0, sizeof(HuffmanTree));
  for (int i = 0; i < n; i++) {
    hft[i + 1].wight = w[i];
  }
}

int main() {
  WeightType w[] = {5, 29, 7, 8, 14, 23, 3, 11};
  HuffmanTree hft = {0};
  InitHuffmanTree(hft, w);
  PrintHuffmanTree(hft);
  CreateHuffmanTree(hft);
  PrintHuffmanTree(hft);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值