路径:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径
路径长度:路径上的分支数目称作路径长度。
树的路径长度:从树根到每一结点的路径长度之和。
带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积。树的带权路径长度为树中所有叶子节点的带权路径长度之和。
带权路径长度最小的二叉数被称为赫夫曼树
struct HaffMan { int weight;//权值 int leftindex;//左孩子的位置 int rightindex;//右孩子的位置 int parentindex;//父节点的位置 int flg;//标记 }; void Create(HaffMan* haff, int* num, int n)//创建赫夫曼树 { int min1, min2, min1index, min2index;//min1最小值,min2次小值,min1index最小值位置,min2index次小值位置 for (int i = 0; i < 2 * n - 1; i++)//n个结点创建赫夫曼树,常见出的赫夫曼树结点为2*n-1 { if (i < n) { haff[i].weight = num[i]; } else haff[i].weight = 0; haff[i].leftindex = -1; haff[i].rightindex = -1; haff[i].parentindex = -1; haff[i].flg = 0;//初始化 } for (int i = 0; i < n-1; i++)//n个节点需要n-1次比较可以找到最小值与次小值 { min1 = min2 = 65535; min1index = min2index = -1; for (int j = 0; j < n + i; j++) { if (haff[j].weight < min1 && haff[j].flg == 0) { min2 = min1; min2index = min1index; min1 = haff[j].weight; min1index = j; } else if (haff[j].weight < min2 && haff[j].flg == 0) { min2 = haff[j].weight; min2index = j; } } //用两个最小的构建新的结点 haff[n + i].weight = min1 + min2; haff[n + i].leftindex = min1index; haff[n + i].rightindex = min2index; haff[min1index].parentindex = n + i; haff[min2index].parentindex = n + i; haff[min1index].flg = haff[min2index].flg = 1; } } void HaffCode(HaffMan*haff,vector<vector<int>>&vv,int n)//构建赫夫曼树编码,左子树为0,右子树为1 { int child, parent; vector<int>s; for (int i = 0; i < n; i++) { child = i; parent = haff[child].parentindex; s.clear();//每次都要清空vector里面的数 while (parent != -1) { if (haff[parent].leftindex==child) s.push_back(0); else s.push_back(1); child = parent; parent = haff[child].parentindex; } vv.push_back(s); } } void main() { vector<vector<int>>vv; int num[] = { 10,30,40,15,5 }; int n = sizeof(num) / sizeof(num[0]); HaffMan haffp[9]; Create(haffp, num, n); HaffCode(haffp, vv, n); for (int i = 0; i < vv.size(); i++) { for (int j = vv[i].size() - 1; j >= 0; j--) { cout << vv[i][j]; } cout << endl; } }
数据结构:赫夫曼树
最新推荐文章于 2024-06-24 22:49:37 发布