C++实现HuffManTree+代码实现

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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈夫曼树是一种基于字符频率来构建的最优二叉树,用于压缩和解压缩数据。在 C++ 中,可以通过以下步骤来实现哈夫曼树: 1. 定义结构体存储哈夫曼树节点信息,包括字符、权值、左右子节点等信息。 ``` struct TreeNode { char ch; int freq; TreeNode *left, *right; }; ``` 2. 构建哈夫曼树的主要过程是先将字符按照频率从小到大排序,然后将最小的两个节点合并为一个新节点,其权值为两个节点权值之和。重复此过程直到只剩下一个节点,即为哈夫曼树的根节点。可以使用 STL 中的 priority_queue 来实现节点合并的过程。 ``` struct cmp { bool operator() (TreeNode* a, TreeNode* b) { return a->freq > b->freq; } }; void buildHuffmanTree(vector<char>& chars, vector<int>& freqs) { priority_queue<TreeNode*, vector<TreeNode*>, cmp> pq; for (int i = 0; i < chars.size(); ++i) { TreeNode* node = new TreeNode(chars[i], freqs[i]); pq.push(node); } while (pq.size() > 1) { TreeNode* left = pq.top(); pq.pop(); TreeNode* right = pq.top(); pq.pop(); TreeNode* parent = new TreeNode('#', left->freq + right->freq); parent->left = left; parent->right = right; pq.push(parent); } } ``` 3. 对于给定的字符串,可以通过哈夫曼树得到每个字符的编码,即左子节点对应编码为 0,右子节点对应编码为 1。可以使用递归的方式遍历哈夫曼树,生成编码表。 ``` unordered_map<char, string> generateCodeMap(TreeNode* root) { unordered_map<char, string> codeMap; function<void(TreeNode*, string)> dfs = [&](TreeNode* node, string code) { if (!node) return; if (node->ch != '#') codeMap[node->ch] = code; dfs(node->left, code + "0"); dfs(node->right, code + "1"); }; dfs(root, ""); return codeMap; } ``` 以上就是使用 C++ 实现哈夫曼树的基本步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值