#include"iostream" #include #include using namespace std; struct HTNode { int weight; // 权值,设为整型 int parent; // 双亲位置 int lchild; // 左孩子位置 int rchild; // 右孩子位置 }; void select(HTNode* HT, int k, int& i1, int& i2) // 在前K-1个结点中选择权值最小的两个根结点i和j { int m1, m2; m1 = m2 = 32767; // i1 = i2 = 0; for (int j = 0; j < k; j++) { if (HT[j].weight < m1 && HT[j].parent == -1) { m2 = m1, i2 = i1; m1 = HT[j].weight; i1 = j; } else if (HT[j].weight < m2 && HT[j].parent == -1) { m2 = HT[j].weight; i2 = j; } } } // 算法5.16 // 构造哈夫曼树 void HuffmanTree(HTNode*& HT, int* w, int n) { // n是叶子结点的个数,w是叶子结点的权值数组 HTNode* p; int k, i; int i1, i2; p = HT; for (i = 0; i < 2 * n - 1; i++) { // 设置初始状态,所有结点的指针为空 HT[i].weight = 0; HT[i].parent = -1; HT[i].lchild = -1; HT[i].rchild = -1; } for (i = 0; i < n; i++) { // 前n个结点的权值分别为个结点的权值 HT[i].weight = w[i]; } for (k = n; k < 2 * n - 1; k++) { // 构造最优二叉树 select(HT, k, i1, i2); // 在前K-1个结点中选择权值最小的两个根结点i1和i2 HT[i1].parent = k; HT[i2].parent = k; HT[k].weight = HT[i1].weight + HT[i2].weight; HT[k].lchild = i1; HT[k].rchild = i2; } } void DispHT(HTNode* HT, int n) // 显示哈夫曼树存储 { HTNode* p; p = HT; cout << "k" << setw(7) << "Weight" << setw(7) << "parent" << setw(7) << "lchild" << setw(7) << "rchild" << endl; for (int k = 0; k < 2 * n - 1; k++) { cout << k << setw(7) << (p + k)->weight << setw(7) << (p + k)->parent << setw(7) << (p + k)->lchild << setw(7) << (p + k)->rchild << endl; } } //算法5.17 // 构建哈夫曼编码 void CreateHFCode(HTNode* HT, int n, char** HC) { int i, start, c, f; char* cd; cd = new char[n]; cd[n - 1] = '\0'; for (i = 0; i < n; i++) { start = n - 1; c = i; f = HT[i].parent; while (f != -1) { if (HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; c = f; f = HT[f].parent; } cout << endl; HC[i] = new char[n - start]; HC[i] = &cd[start]; int j = 0; while (HC[i][j] != '\0') // 显示编码 { cout << HC[i][j]; j++; } } delete cd; cout << endl; } int op; int main() { int* w; // 权值数组 int n; // 权值个数 int i; // 工作变量 HTNode* HT; // 哈夫曼树 char** HC; do { cout << "1-输入结点权值" << endl; cout << "2-生成最优二叉树" << endl; cout << "3-求哈夫曼编码" << endl; cout << "4-退出程序" << endl; cout << "请选择操作(1~4):"; cout << "\b\b"; cin >> op; switch (op) { case 1: cout << "测试案例" << endl; cout << "7,5,2,3,5,6" << endl; cout << "请输入结点的个数:"; cin >> n; w = new int[n]; cout << "请依次输入权值:" << endl; for (i = 0; i < n; i++) { cout << "请输入第" << i + 1 << "个权值:"; cin >> w[i]; } break; case 2: HT = new HTNode[2 * n - 1]; // 申请最优二叉树存储空间 HuffmanTree(HT, w, n); cout << "创建的哈夫曼树为:\n"; DispHT(HT, n); system("pause"); break; case 3: HC = new char* [n]; // 存储哈示曼编码 cout << "哈夫曼编码为:\n"; CreateHFCode(HT, n, HC); break; case 4: cout << "结束运行,Bye-Bye!" << endl; break; } } while (op != 4); return 0; }