在电脑资料处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。 http://zh.wikipedia.org/zh-cn/%E9%9C%8D%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81 /*插入*/ void InsertHTNode(HTNode* hTree, int const len) // 将最后一个元素按照升序插入到合适的位置上 { int i = 0; for (; hTree[i].wt < hTree[len-1].wt && i < len; i++) // 因为最后一个是本身,所以可以保证i不越界 { } // 将从i开始的所有元素向后移动一位 HTNode temp = hTree[len-1]; int j = len - 1; while (i < j) { // 将位置j-1上的元素移动到位置j上 hTree[j] = hTree[j-1]; j--; } hTree[i] = temp; // 将hTree[len-1]移动到合适的位置 } /* 创建Huffman树 */ HTNode* CreateHuffmanTree(HTNode const * hLeaf, int const nLeafNodes) // 构建Huffman树 { int const totalNum = 2 * nLeafNodes - 1; int left = 0, right = nLeafNodes - 1; // 左右指针 /*假设hLeaf中节点已经按照权重升序排好序了*/ HTNode* hTree = new HTNode[totalNum]; assert(hTree != 0); memcpy(hTree, hLeaf, nLeafNodes * sizeof(HTNode)); while (left < right) { // 取头两个元素(最小的)创建新节点 hTree[++right].wt = hTree[left].wt + hTree[left+1].wt; hTree[right].lChild = &hTree[left++]; hTree[right].rChild = &hTree[left++]; // 将新节点插入到合适的位置 InsertHTNode(&hTree[left], right-left+1); } //return &hTree[totalNum-1]; // 返回根节点 return hTree; } 示例测试代码 // Huffman Tree /*假设所有的叶子节点都是按升序排列的*/ int const nNodes = 4; HTNode hTNode[nNodes]; hTNode[0].wt = 1; hTNode[1].wt = 3; hTNode[2].wt = 5; hTNode[3].wt = 7; HTNode* hTree = CreateHuffmanTree(hTNode, nNodes); HTNode* rt = hTree + 2 * nNodes - 2; if (hTree) { preorder_nonrecursive(rt); cout << endl; inorder_nonrecursive(rt); cout << endl; } // Tidy if (hTree) { delete[] hTree; }