数据结构之Huffman树的C++实现

1、HUffman树百度百科的定义以下:ios

  给定N个权值做为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。函数

2、Huffman树的构造方法:测试

  一、在N个节点组成的节点集合中选取两个权值最小的节点组成一棵树,新树的根节点的权值为两个节点权值之和。spa

  二、在节点集合中删除这两个节点。code

  三、将根节点加入节点集合blog

  四、重复以上过程直到节点集合中只剩一个节点队列

            

          节点集合{1,2,3,4,5}get

 

    

    在节点集合中删除最小的两个节点,加入新的节点it

           

 

     构造完成后的Huffman树
io

3、Huffman树的C++实现

  由上面的过程看一个Huffman树上的节点定义能够以下:

  权值(weight)、父节点位置(parent)、左右儿子节点位置(lchild、rchild)

 1 #include<iostream>
 2 #include<queue>
 3 #include<vector>
 4 using namespace std;
 5 struct Huffman {
 6     int weight;//权值
 7     int lchild, rchild;//左、右孩子
 8     int parent;//父节点
 9 
10 //这个构造函数是由于最开始每一个节点都是单独的树,儿子节点父节点均不存在
11 //方便初始化
12   Huffman(int w){
13         weight = w;
14         lchild = -1;
15         rchild = -1;
16         parent = -1;
17 }
18     Huffman(int w,int l,int r,int p) {
19         weight = w;
20         lchild = l;
21         rchild = r;
22         parent = p;
23     }
24 
25 };

  咱们能够用vector定义一个节点集合,叫作Huffman表

 1 vector<Huffman> arg;//Huffman表
 2 //构造Huffman树并返回Huffman树头位置
 3 int Huffman_head() {
 4     int n = (int)arg.size();//元素计数器
 5     while (n!=1) {
 6         int min_1 = -1;
 7         int min_2 = -1;
 8 //在节点集合中找到最小的元素
 9         for (int min_k = 0; min_k < (int)arg.size(); min_k++) {
10             if (arg.at(min_k).parent != -1)
11                 continue;
12             if (min_1 == -1)
13                 min_1 = min_k;
14             if (arg.at(min_k).weight < arg.at(min_1).weight)
15                 min_1 = min_k;
16         }
17         arg.at(min_1).parent = (int)arg.size();
18 //在节点集合中找到第二小的元素
19         for (int min_k = 0; min_k < (int)arg.size(); min_k++) {
20             if (arg.at(min_k).parent != -1)
21                 continue;
22             if (min_2 == -1)
23                 min_2 = min_k;
24             if (arg.at(min_k).weight < arg.at(min_2).weight)
25                 min_2 = min_k;
26         }
27         arg.at(min_2).parent = (int)arg.size() ;
28         Huffman x (arg.at(min_1).weight + arg.at(min_2).weight, min_1, min_2, -1);
29         arg.push_back(x);//加入新节点
30         n--;
31         
32     }
33     
34     return (int)arg.size() - 1;//最后的节点必定是最末尾的值
35 
36 }

  利用队列打印Huffman表

 1 void print(int head) {
 2     queue<int> pr;
 3     cout<<"Num\t" << "weight\t" << "lchlid\t" << "rchild\t" << "parent\t" << endl;
 4     pr.push(head);
 5     while (!pr.empty()) {
 6         int  x = pr.front();
 7         if(arg.at(x).lchild != -1)
 8             pr.push(arg.at(x).lchild);
 9         if(arg.at(x).rchild != -1)
10             pr.push(arg.at(x).rchild);
11         cout << x << "\t" << arg.at(x).weight << "\t" << arg.at(x).lchild << "\t" << arg.at(x).rchild << "\t" << arg.at(x).parent << "\t" << endl;
12         pr.pop();
13     }
14     
15 
16 }

  测试代码

int main() {
    arg = { {1},{2},{3},{4},{5} };
    int p = Huffman_head();
    print(p);
    return 0;
}

  结果以下

这只是Huffman树最简单的构造方法之一,Huffman树有不少应用,压缩与解压缩就与它有关。

 。

相关文章
相关标签/搜索