//jianfeng Hu,2016.11.10 //哈夫曼树 #include<iostream> #include<string> using namespace std; typedef struct { int weight; int parent, lch, rch; }HTNode, *HuffmanTree; typedef char **HuffmanCode; void Select(HuffmanTree HT, int yu, int *s1, int *s2) { int sl1 = 0, sl2 = 0; for (int i = 1; i <= yu; i++) { if (HT[i].parent == 0) { if (sl1 == 0) sl1 = i; else if (sl2 == 0) sl2 = i; else { if ((HT[i].weight < HT[sl2].weight) || (HT[i].weight < HT[sl1].weight)) { if (HT[sl1].weight > HT[sl2].weight) sl1 = i; else sl2 = i; } } } } *s2 = (sl1 > sl2 ? sl1 : sl2); *s1 = (sl1 < sl2 ? sl1 : sl2); } void CreatHuffmanTree(HuffmanTree &HT, int n) { if (n <= 1) return; int m = 2 * n - 1; HT = new HTNode[m + 1]; for (int i = 1; i <= m; i++) { HT[i].lch = 0; HT[i].rch = 0; HT[i].parent = 0; } cout << "请依次输入每一个字符的权值:";//输入 for (int i = 1; i <= n; ++i) { cin >> HT[i].weight; } //构造 int s1, s2; for (int i = n + 1; i <= m; ++i) { Select(HT, i - 1, &s1, &s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lch = s1; HT[i].rch = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; } //输出验证 cout << "i\tweight\tparent\tlc\trc" << endl; for (int i = 1; i <= m; i++) { cout << i << "\t" << HT[i].weight << "\t" << HT[i].parent << "\t" << HT[i].lch << "\t" << HT[i].rch << endl; } } void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n) { int start, c, f; char *cd = new char[n]; HC = new char*[n + 1]; cd[n - 1] = '\0'; cout << "每个字符的哈夫曼编码:" << endl; for (int i = 1; i <= n; ++i) { start = n - 1; c = i; f = HT[i].parent; while (f != 0) { --start; if (HT[f].lch == c) cd[start] = '0'; else cd[start] = '1'; c = f; f = HT[f].parent; } HC[i] = new char[n - start]; strcpy(HC[i], &cd[start]); cout << HC[i] << " "; } delete cd; } void main() { int n; HuffmanTree HT = NULL; HuffmanCode HC; cout << "请输入结点的个数:"; cin >> n; CreatHuffmanTree(HT, n); CreatHuffmanCode(HT, HC, n); }
你是用VS2015编写的吧,在VS2015中使用strcpy是不安全的,strcpy_s是strcpy的安全版本。但是好像使用strcpy_s在这里不行,所以要解决stycpy在VS2015中正常使用的方法,最简单的方法是在程序前面加上句“#pragmawarning(disable:4996)”
附成功截图:
我改好了,但是还是谢谢你
@丶枫: 来443谢我吧😁
@Dmego: 来找我就好
#include <iostream> #include <string> #include <vector> #include<algorithm> using namespace std; class Huffman { public: char elementChar;//节点元素 int weight;//权重 char s;//哈夫曼编码 Huffman* parent;//父节点 Huffman* leftChild;//左孩子 Huffman* rightChild;//右孩子 public: Huffman(); Huffman(char a, int weight); bool operator < (const Huffman &m)const { return weight < m.weight;} }; Huffman::Huffman() { this->s = ' '; this->elementChar = '*';//非叶子节点 this->parent = this->leftChild = this->rightChild = NULL; } Huffman::Huffman(char a, int weight):elementChar(a),weight(weight) { this->s = ' '; this->elementChar = '*';//非叶子节点 this->parent = this->leftChild = this->rightChild = NULL; } //递归输出哈夫曼值 void huffmanCode(Huffman & h) { if(h.leftChild == NULL && h.rightChild == NULL) { //如果是叶子节点,输出器哈夫曼编码 string s; Huffman temp = h; while(temp.parent != NULL) { s = temp.s + s; temp = *temp.parent; } cout << h.elementChar << "的哈夫曼编码是:" << s << endl; return; } //左孩子 huffmanCode(*h.leftChild); //右孩子 huffmanCode(*h.rightChild); } int main() { string huffmanStr; cout << "请输入一串字符序列:" << endl; cin >> huffmanStr; //得到字符串信息 int j,n,m[100],h,k=0; char cha[100]; n = huffmanStr.length(); cout << "字符串总共有字符" << n << "个" << endl; for(int i1 = 0; i1 < n; i1++) { j = 0; h = 0; while(huffmanStr[i1] != huffmanStr[j]) j++; if(j == i1) { cha[k] = huffmanStr[i1]; cout << "字符" << cha[k] << "出现"; } //如果j !=i1 则略过此次循环 else continue; for(j = i1; j < n; j++) { if(huffmanStr[i1] == huffmanStr[j]) h++; } cout << h << "次" << endl; m[k] = h; k++; } //哈夫曼编码 Huffman huffmanTemp; vector < Huffman > huffmanQueue; //初始化队列 for(int i = 0; i < k; i++) { huffmanTemp.elementChar = cha[i]; huffmanTemp.weight = m[i]; huffmanQueue.push_back(huffmanTemp); } //得到哈夫曼树所有节点 int huffmanQueue_index = 0; sort(huffmanQueue.begin(), huffmanQueue.end()); while(huffmanQueue.size() < 2 * k - 1) { //合成最小两个节点的父节点 huffmanTemp.weight = huffmanQueue[huffmanQueue_index].weight + huffmanQueue[huffmanQueue_index + 1].weight; huffmanQueue[huffmanQueue_index].s = '0'; huffmanQueue[huffmanQueue_index + 1].s = '1'; huffmanTemp.elementChar = '*'; //将父节点加入队列 huffmanQueue.push_back(huffmanTemp); sort(huffmanQueue.begin(), huffmanQueue.end()); huffmanQueue_index += 2; } //把所有节点构造成哈夫曼树 int step = 0;//步长 while(step + 2 < 2 * k) { for(int j = step + 1; j <= huffmanQueue.size(); j++) { if(huffmanQueue[j].elementChar == '*' && huffmanQueue[j].leftChild == NULL && (huffmanQueue[j].weight == huffmanQueue[step].weight + huffmanQueue[step+1].weight)) { huffmanQueue[j].leftChild = &huffmanQueue[step]; huffmanQueue[j].rightChild = &huffmanQueue[step+1]; huffmanQueue[step].parent = huffmanQueue[step+1].parent = &huffmanQueue[j]; break; } } step += 2; } //cout << huffmanQueue.size() << endl; //序列最后一个元素,即哈弗曼树最顶端的节点 huffmanTemp = huffmanQueue.back(); huffmanCode(huffmanTemp); return 0; }