利用哈夫曼编码实现显示DOS的Tree

第一次写博客,有点小紧张

最近在上数据结构专周,实现哈夫曼的编码和译码,最后为了实现直观的显示出树,于是仿造dos的tree命令,实现了显示生成的哈夫曼

原理差不多就是树的前序遍历,每一行代表每次输出的一个节点

但是对于每个节点的输出有不同的处理方式

1.根节点直接输出

2.按照当前的层数输出"│ "或"     "

3.右孩子输出"└─"后输出节点,左孩子输出"├─"后输出节点

4.这样打印出来的树有多余的"│ "


//显示生成的哈夫曼树
//huffTree:生成好的哈夫曼树
//node:当前要显示的节点
//n:当前节点的层数,是从0开始的
void PrintTree(Element* & huffTree, int node, int n)
{
    if(node != -1)
    {
        //得到当前节点的父节点
        int parent = huffTree[node].parent;
        //等于0代表根节点,直接输出节点的值
        if(n == 0)
        {
            cout<<huffTree[node].value<<endl;
            PrintTree(huffTree, huffTree[node].lchild, n+1);
            PrintTree(huffTree, huffTree[node].rchild, n+1);
        }
        else
        {
            for(int i = 1 ; i < n ; i++)
            {
                cout<<"│  ";
            }
            //如果是右孩子,就输出"└─"后输出节点值
            if(huffTree[parent].rchild == node)
            {
                cout<<"└─"<<huffTree[node].value<<endl;
            }
            //如果是左孩子,就输出"├─"后输出节点值
            else
            {
                cout<<"├─"<<huffTree[node].value<<endl;
            }
            PrintTree(huffTree, huffTree[node].lchild, n+1);
            PrintTree(huffTree, huffTree[node].rchild, n+1);
        }
    }
}
5.于是为了处理掉多余的"│ ",发现先如果该节点是右子树,并且节点不是根节点,则该节点子树节点就不输出该层的"│ ",而用“    ”占位

由于不是该节点的子树仍可能输出"│ ",有一个返回时去掉不输出层的过程

于是就创建了一个数组num来记录不输出"│ "而用“    ”代替的节点的层数,num[0]记录个数

多了代码

            for(int i = 1 ; i < n ; i++)
            {
                bool flag = false;
                //判断第i层是否是不输出"│  "而用"   "代替
                for(int j = 1 ; j <= num[0] ; j++)
                {
                    if(i == num[j])
                    {
                        cout<<"    ";
                        flag = true;
                        break;
                    }
                }
                if(!flag)
                {
                    cout<<"│  ";
                }

            }

            //该节点是右孩子
            if(huffTree[parent].rchild == node)
            {
                cout<<"└─"<<huffTree[node].value<<endl;
                //该节点是内节点,不是叶子节点,用num记下层数
                if(huffTree[node].rchild != -1)
                {
                    num[++num[0]] = n;
                }
            }
还有

            //去除掉不输出的层数
            if(huffTree[parent].rchild == node)
            {
                if(huffTree[node].rchild != -1)
                {
                    num[0]--;
                }
            }

//显示生成的哈夫曼树
//huffTree:生成好的哈夫曼树
//node:当前要显示的节点
//n:当前节点的层数,是从0开始的
//num:不需要显示"│  "的层数,num[0]储存个数
void PrintTree(Element* & huffTree, int node, int n, int num[])
{
    if(node != -1)
    {
        //得到当前节点的父节点
        int parent = huffTree[node].parent;
        //等于0代表根节点,直接输出节点的值
        if(n == 0)
        {
            cout<<huffTree[node].value<<endl;
            PrintTree(huffTree, huffTree[node].lchild, n+1, num);
            PrintTree(huffTree, huffTree[node].rchild, n+1, num);
        }
        else
        {
            for(int i = 1 ; i < n ; i++)
            {
                bool flag = false;
                //判断是否有不输出"│  "的层数
                for(int j = 1 ; j <= num[0] ; j++)
                {
                    if(i == num[j])
                    {
                        cout<<"    ";
                        flag = true;
                        break;
                    }
                }
                if(!flag)
                {
                    cout<<"│  ";
                }

            }
            //如果是右孩子,就输出
            if(huffTree[parent].rchild == node)
            {
                cout<<"└─"<<huffTree[node].value<<endl;
                //如果是右孩子且是内节点,则后面子树在该层就不输出"│  ",而用空格"    "代替
                //用num记下层数
                if(huffTree[node].rchild != -1)
                {
                    num[++num[0]] = n;
                }
            }
            else
            {
                cout<<"├─"<<huffTree[node].value<<endl;
            }
            PrintTree(huffTree, huffTree[node].lchild, n+1, num);
            PrintTree(huffTree, huffTree[node].rchild, n+1, num);
            //去除掉不输出的层数
            if(huffTree[parent].rchild == node)
            {
                if(huffTree[node].rchild != -1)
                {
                    num[0]--;
                }
            }
        }
    }
} 
基于VC++6.0,注意:用的是邻接表而非邻接多重表,如果老师比较严格就不要用这份了,如果出错就找到c_file文件重新加载就可以了 基于哈夫曼(Huffmen)编码的通信系统的设计与实现 【问题描述】 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼的编/译码系统。 【基本要求】 一个完整的系统应具有以下功能: 1.I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 2.E:编码(Encoding)。利用以建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 3.D:译码(Decoding)。利用已经建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。 4.P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码,同时将此字符形式的编码写入文件CodePrint中。 5.T:打印哈夫曼树(Tree printing)。将已经在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值