数据结构C++语言版 -- 霍夫曼树

大二学生的 C++数据结构 有部分Openjudge提交的代码没有删除

邮箱:liu_772021@yeah.net

欢迎交流讨论~

有用的话,点赞留言就可以表示感谢啦



#include <queue>
#include <iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;

typedef struct tnode
{
    /* data */
    ElemType data;
    int w;
    char v;
    struct tnode *lchild, *rchild;
} BTNode;

void CreateBTree(BTNode *&bt, char *str) //由括号表示串创建二叉链
{
    BTNode *St[MaxSize], *p = NULL;
    int top = -1, k, j = 0;
    char ch;
    bt = NULL; //建立的二叉树初始时为空
    ch = str[j];
    while (ch != '\0') //str未扫描完时循环
    {
        switch (ch)
        {
        case '(':
            top++;
            St[top] = p;
            k = 1;
            break; //为左孩子结点
        case ')':
            top--;
            break;
        case ',':
            k = 2;
            break; //为右孩子结点
        default:
            p = new BTNode();
            p->data = ch;
            p->lchild = p->rchild = NULL;
            if (bt == NULL) //*p为二叉树的根结点
                bt = p;
            else //已建立二叉树根结点
            {
                switch (k)
                {
                case 1:
                    St[top]->lchild = p;
                    break;
                case 2:
                    St[top]->rchild = p;
                    break;
                }
            }
        }
        j++;
        ch = str[j];
    }
}
void DestroyBTree(BTNode *&bt)
{
    if (bt == NULL)
        return;
    DestroyBTree(bt->lchild);
    DestroyBTree(bt->rchild);
    free(bt);
    bt = NULL;
}
int leafcount(BTNode *bt)
{
    if (bt == nullptr)
        return 0;
    int m, n;
    if (bt->lchild == nullptr && bt->rchild == nullptr)
        return 1;
    else
    {
        m = leafcount(bt->rchild);
        n = leafcount(bt->lchild);
        return m + n;
    }
}
int leafcount2(BTNode *bt, int &leaves)
{
    if (bt == nullptr)
        return 1;
    int m = leafcount2(bt->lchild, leaves);
    int n = leafcount2(bt->rchild, leaves);
    if (m + n == 2)
        leaves++;
    return 0;
}
#include <stack>
void encode(BTNode *&bt, char v[], int w[])
{
    stack<BTNode *> st;
    BTNode *cur = bt, *top;
    int i = 0;
    while (cur != nullptr || !st.empty())
    {
        while (cur != nullptr)
        {
            st.push(cur);
            if (cur->lchild == nullptr && cur->rchild == nullptr)
            {
                cur->v = v[i];
                cur->w = w[i];
                i++;
            }
            else
            {
                cur->v = '_';
                cur->w = 0;
            }
            cur = cur->lchild;
        }
        top = st.top();
        st.pop();
        cur = top->rchild;
    }
}

void cal_weight(BTNode *&bt, int leaves)
{
    BTNode *cur = bt;
    stack<BTNode *> st;
    while (leaves > 1)
    {
        st.push(cur);
        cur = cur->lchild;
        leaves--;
    }
    while (!st.empty())
    {
        BTNode *temp = st.top();
        temp->w = temp->lchild->w + temp->rchild->w;
        st.pop();
    }
}

void output_leaf(BTNode *bt)
{
    if (bt == nullptr)
        return;
    if (bt->lchild == nullptr && bt->rchild == nullptr)
        cout << bt->data << " ";
    else
    {
        output_leaf(bt->lchild);
        output_leaf(bt->rchild);
        return;
    }
}

void output_non_leaf(BTNode *bt, int leaves)
{
    BTNode *cur = bt;
    stack<ElemType> st;
    while (leaves > 1)
    {
        st.push(cur->data);
        cur = cur->lchild;
        leaves--;
    }
    while (!st.empty())
    {
        cout << st.top() << " ";
        st.pop();
    }
}

void output_non_leaf_weight(BTNode *bt, int leaves)
{
    BTNode *cur = bt;
    stack<int> st;
    while (leaves > 1)
    {
        st.push(cur->w);
        cur = cur->lchild;
        leaves--;
    }
    while (!st.empty())
    {
        cout << st.top() << " ";
        st.pop();
    }
}

void output_leaf_code(BTNode *bt,int level)
{
    if (bt == nullptr)
        return;
    if (bt->lchild == nullptr && bt->rchild == nullptr)
    {
        for(int i=0;i<level-1;i++){
            cout<<0;
        }
        if(bt->w==1)cout<<0<<" ";
        else cout<<1<<" ";
    }
    else
    {
        output_leaf_code(bt->lchild,level+1);
        output_leaf_code(bt->rchild,level+1);
        return;
    }
}

#include <sstream>
int main()
{
    ElemType tree[MaxSize];
    cin >> tree;
    BTNode *bt;
    CreateBTree(bt, tree);

    int leaves = leafcount(bt); // 计算叶节点数量

    char v[MaxSize];
    int w[MaxSize];
    for (int i = 0; i < leaves; i++)
        cin >> v[i];
    for (int i = 0; i < leaves; i++)
        cin >> w[i]; // 输入数据

    output_non_leaf(bt, leaves);
    cout << endl; // 输出非叶子节点

    encode(bt, v, w);
    cal_weight(bt, leaves);

    output_non_leaf_weight(bt, leaves); // 输出非叶子节点的权重
    cout << endl;

    output_leaf(bt);                     // 输出叶子节点
    cout << endl;

    output_leaf_code(bt,0);        // 输出编码
    cout<<endl;

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值