1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include<iostream> #include<cstdlib> #include<cstring> using namespace std;
typedef struct { char sign; int weight; unsigned int parent, lchild, rchild; }HTNode, * HuffmanTree; typedef struct{ char **NodesCode; char *sign; }HuffmanCode;
void Select(HuffmanTree HT, int p, int& s1, int& s2); void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int* w, char *s, int n); void HuffmanCodePrint(HuffmanCode HC, int n); int main() { HuffmanTree HT; HuffmanCode HC; int n; cout << "Input the number of chars: "; cin >> n; int *w = new int[n]{}; char *s = new char[n]{}; cout << "Input n chars in the tuple:(char, weight):\n"; for (int i = 0; i < n; i++) { cin >> s[i] >> w[i]; } HuffmanCoding(HT, HC, w, s, n); HuffmanCodePrint(HC, n); return 0; } void Select(HuffmanTree HT, int p, int& s1, int& s2) { s1 = s2 = 0; for (int i = 1; i <= p; i++) { if (HT[i].parent) continue; else { if (!s1) s1 = i; else if (!s2) { if (HT[s1].weight > HT[i].weight) { s2 = s1; s1 = i; } else s2 = i; } else { if (HT[i].weight < HT[s1].weight) { s2 = s1; s1 = i; } else if (HT[i].weight < HT[s2].weight) { s2 = i; } } } } return; }
void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int* w, char *s, int n) {
if (n <= 1) return; int m = 2 * n - 1; HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); HuffmanTree p = HT; int i = 1; for (p=HT+1; i <= n; ++i, ++p, ++w, ++s) *p = {*s,*w,0,0,0 }; for (; i <= m; i++, p++) *p = {0,0,0,0,0 }; for (i = n + 1; i <= m; i++) { int s1 = 0, s2 = 0; 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; }
HC.NodesCode = (char**)malloc((n + 1) * sizeof(char*)); HC.sign = (char*)malloc((n+1) * sizeof(char)); char* cd = (char*)malloc(n * sizeof(char)); cd[n - 1] = '\0'; for (i = 1; i <= n; ++i) { int start = n - 1; for (int c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) if (HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; HC.NodesCode[i] = (char*)malloc((n - start) * sizeof(char)); HC.sign[i] = HT[i].sign; strcpy(HC.NodesCode[i], &cd[start]); } free(cd); return; } void HuffmanCodePrint(HuffmanCode HC, int n) { cout << "Chars Huffmancodes:\n"; for (int i = 1; i <= n; i++) { cout << HC.sign[i] << ": " << HC.NodesCode[i] << endl; } return; }
|