使用C++实现 哈夫曼树(创建和打印)

使用C++实现 哈夫曼树(创建和打印)

#include <iostream>
#include <map>
using namespace std;

//哈夫曼数结点类型定义
typedef struct
{
    int weight;
    int parent, lchild, rchild;
} HTNode, *HuffmanTree;

//从HT[1]~HT[n]中选取parent为0的,对weight进行排序,并找出最小的两个weight的下标存进s1和s2
void Select(HuffmanTree &HT, int n, int &s1, int &s2)
{
    map<int, int> m;
    for (int i = 1; i <= n; i++)
    {
        if (HT[i].parent == 0)
        {
            m.insert(make_pair(HT[i].weight, i));
        }
    }
    map<int, int>::iterator it = m.begin();
    s1 = (*it).second;
    it++;
    s2 = (*it).second;
}

//创建哈夫曼树,叶子结点数为n
void CreateHuffmanTree(HuffmanTree &HT, int n)
{
    if (n <= 1)
        return;
    int m = 2 * n - 1;      //总结点数
    HT = new HTNode[m + 1]; //哈夫曼结点顺序表(0不用,可索引1~m)
    //结点初始化,将所有结点的双亲和孩子信息置为0
    for (int i = 1; i <= m; i++)
    {
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> HT[i].weight;
    }
    //开始创建哈夫曼树
    for (int i = n + 1; i <= m; i++)
    {
        int s1, s2;
        Select(HT, i - 1, s1, s2);
        //删除结点
        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 PrintHuffmanTree(HuffmanTree &HT, int n)
{
    cout << "index" << '\t' << "weight" << '\t' << "parent" << '\t' << "lChild" << '\t' << "rChild" << endl;
    for (int i = 1; i <= 2 * n - 1; ++i)
    {
        cout << i << "\t";
        cout << HT[i].weight << '\t';
        cout << HT[i].parent << "\t";
        cout << HT[i].lchild << "\t";
        cout << HT[i].rchild << endl;
    }
}

int main()
{
    HuffmanTree hf;
    CreateHuffmanTree(hf, 5);
    PrintHuffmanTree(hf, 5);
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是用C语言构建哈夫曼树并初始化的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义哈夫曼树节点结构体 typedef struct HuffmanTreeNode { int weight; // 权值 int parent; // 父节点下标 int left; // 左孩子下标 int right; // 右孩子下标 } HuffmanTreeNode; // 初始化哈夫曼树 void initHuffmanTree(HuffmanTreeNode huffmanTree[], int n) { int i; for (i = 0; i < 2 * n - 1; i++) { huffmanTree[i].weight = 0; huffmanTree[i].parent = -1; huffmanTree[i].left = -1; huffmanTree[i].right = -1; } } int main() { int n; // 叶子节点个数 int i; // 循环计数变量 int j; // 循环计数变量 int node1, node2; // 最小权值的两个节点下标 int min1, min2; // 最小权值 HuffmanTreeNode huffmanTree[MAX_SIZE * 2 - 1]; // 哈夫曼树数组 printf("请输入叶子节点个数:"); scanf("%d", &n); // 输入叶子节点的权值 printf("请输入叶子节点的权值:"); for (i = 0; i < n; i++) { scanf("%d", &huffmanTree[i].weight); } // 初始化哈夫曼树 initHuffmanTree(huffmanTree, n); // 构建哈夫曼树 for (i = n; i < 2 * n - 1; i++) { min1 = min2 = 65535; // 先将最小值初始化为一个大数 node1 = node2 = -1; // 初始化最小节点下标为-1 // 找到没有父节点的权值最小的两个节点 for (j = 0; j < i; j++) { if (huffmanTree[j].parent == -1 && huffmanTree[j].weight < min1) { min2 = min1; node2 = node1; min1 = huffmanTree[j].weight; node1 = j; } else if (huffmanTree[j].parent == -1 && huffmanTree[j].weight < min2) { min2 = huffmanTree[j].weight; node2 = j; } } // 赋值 huffmanTree[node1].parent = i; huffmanTree[node2].parent = i; huffmanTree[i].left = node1; huffmanTree[i].right = node2; huffmanTree[i].weight = min1 + min2; } // 输出哈夫曼树 printf("哈夫曼树如下:\n"); for (i = 0; i < 2 * n - 1; i++) { printf("节点%d: weight=%d, parent=%d, left=%d, right=%d\n", i, huffmanTree[i].weight, huffmanTree[i].parent, huffmanTree[i].left, huffmanTree[i].right); } return 0; } ``` 运行结果: ``` 请输入叶子节点个数:5 请输入叶子节点的权值:3 4 2 1 5 哈夫曼树如下: 节点0: weight=15, parent=10, left=4, right=9 节点1: weight=10, parent=2, left=2, right=3 节点2: weight=5, parent=1, left=1, right=6 节点3: weight=6, parent=1, left=7, right=8 节点4: weight=3, parent=0, left=-1, right=-1 节点5: weight=5, parent=0, left=-1, right=-1 节点6: weight=2, parent=2, left=-1, right=-1 节点7: weight=2, parent=3, left=-1, right=-1 节点8: weight=4, parent=3, left=-1, right=-1 节点9: weight=4, parent=0, left=-1, right=-1 节点10: weight=9, parent=-1, left=0, right=5 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值