首页 新闻 搜索 专区 学院

Huffman树做了好久,就是打印不出来他的编码,我感觉和别人的一样啊,好奇怪,求指导

0
悬赏园豆:20 [已关闭问题] 关闭于 2016-11-13 20:13
//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);
}
c++
丶枫的主页 丶枫 | 菜鸟二级 | 园豆:216
提问于:2016-11-13 15:37
< >
分享
所有回答(2)
0

你是用VS2015编写的吧,在VS2015中使用strcpy是不安全的,strcpy_s是strcpy的安全版本。但是好像使用strcpy_s在这里不行,所以要解决stycpy在VS2015中正常使用的方法,最简单的方法是在程序前面加上句“#pragmawarning(disable:4996)”

附成功截图:

Dmego | 园豆:246 (菜鸟二级) | 2016-11-15 12:06

我改好了,但是还是谢谢你

支持(0) 反对(0) 丶枫 | 园豆:216 (菜鸟二级) | 2016-11-15 12:08

@丶枫: 来443谢我吧😁

支持(0) 反对(0) Dmego | 园豆:246 (菜鸟二级) | 2016-11-15 12:40

@Dmego: 来找我就好

支持(0) 反对(0) 丶枫 | 园豆:216 (菜鸟二级) | 2016-11-15 18:55
0
#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;
}

fcyh | 园豆:568 (小虾三级) | 2017-04-04 13:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册