zoukankan      html  css  js  c++  java
  • 网易游戏2015 在线笔试题(5)

    题目

    如下图:
    wangyi501
    wangyi502

    分析

    哈夫曼编码问题!

    程序实现

    #include <iostream>
    #include <cstdlib>
    #include <string>
    
    using namespace std;
    
    const int MAXLEN = 100;
    
    typedef struct Huffmantree
    {
        char ch; /*键值*/
        int weight, mark; /*weight为权值,mark为标志域*/
        struct Huffmantree *parent, *lchild, *rchild, *next;
    
    }Hftree, *linktree;
    
    /*整理输入的字符串,合并相同的项,并求出每个字符在数组中出现的次数 */
    linktree tidycharacter(char character[])
    {
        int i = 0;
        linktree tree, ptr, beforeptr, node; /*链式 ,tree为头结点,beforeptr为ptr的前一结点,node为新申请的结点*/
    
        tree = (linktree)malloc(sizeof(Hftree));/*创建单链表的头结点*/
        if (!tree)return NULL;
        tree->next = NULL; /* 头结点为空,且后续结点为空*/
    
        for (i = 0; character[i] != ''&&character[i] != '
    '; i++) /*遍历直到字符串结束为止*/
        {
            ptr = tree;
            beforeptr = tree;
    
            /*新申请结点node*/
            node = (linktree)malloc(sizeof(Hftree)); 
            if (!node)return NULL;
            node->next = NULL;
            node->parent = NULL;
            node->lchild = NULL;
            node->rchild = NULL; /*置空*/
            node->mark = 0;
            node->ch = character[i];
            node->weight = 1;
    
            /*头结点的下一结点为空,连接node*/
            if (tree->next == NULL)
                tree->next = node; 
            else
            {
                ptr = tree->next;
                while (ptr&&ptr->ch != node->ch)
                {
                    /*将指针移至链表尾*/
                    ptr = ptr->next;
    
                    /*后移*/
                    beforeptr = beforeptr->next; 
                }
                if (ptr&&ptr->ch == node->ch)
                {
                    /*如果链表中某结点的字符与新结点的字符相同*/
                    /*将该结点的权加一*/
                    ptr->weight = ptr->weight + 1;
                    free(node); /*释放node结点的存储空间*/
                }
                else
                {
                    /*新结点与表中结点不相同,将新结点插入链表后*/
                    node->next = beforeptr->next;
    
                    /*node连接在beforeptr之后*/
                    beforeptr->next = node;
                }//else
            }
        }
        return tree;
    }
    
    /*将整理完的字符串按出现次数从小到大的顺序排列 */
    linktree taxisnode(linktree tree)
    {
        linktree head, ph, pt, beforeph; /*head为新链表的表头结点*/
    
        head = (linktree)malloc(sizeof(Hftree));/*创建新链表的头结点*/
        if (!head)return NULL;
        head->next = NULL; /*新结点的头结点为空,后续结点也为空*/
    
        ph = head;
        beforeph = head;
    
        while (tree->next)
        {
            pt = tree->next;/*取被操作链表的首元结点*/
            tree->next = pt->next;
            pt->next = NULL; /*取出pt所指向的结点*/
    
            ph = head->next;
            beforeph = head;
    
            if (head->next == NULL)
                head->next = pt;/*创建当前操作链表首元结点*/
            else
            {
                while (ph&&ph->weight<pt->weight)
                {/*将被操作结点插入相应位置*/
                    ph = ph->next;
                    beforeph = beforeph->next;
                }
                pt->next = beforeph->next;
                beforeph->next = pt;
            }
        }
        free(tree);
        return head;
    }
    
    /*用排完序的字符串建立霍夫曼树 */
    linktree createHftree(linktree tree)
    {
        linktree p, q, newnode, beforep;
    
        for (p = tree->next, q = p->next; p != NULL&&q != NULL; p = tree->next, q = p->next)
        {
            tree->next = q->next;
            q->next = NULL;
            p->next = NULL;
    
            newnode = (linktree)malloc(sizeof(Hftree));/*申请新结点作为霍夫曼树的中间结点*/
            if (!newnode)return NULL;
            newnode->next = NULL;
            newnode->mark = 0;
    
            newnode->lchild = p;/*取链表头结点后的两个结点作为新结点的左、右儿子*/
            newnode->rchild = q;
            p->parent = newnode;
            q->parent = newnode;
            newnode->weight = p->weight + q->weight;
    
            p = tree->next;
            beforep = tree;
    
            if (p != NULL&&p->weight >= newnode->weight)/*将新结点插入原链表的相应位置*/
            {
                newnode->next = beforep->next;
                beforep->next = newnode;
            }
            else
            {
                while (p != NULL&&p->weight<newnode->weight)
                {
                    p = p->next;
                    beforep = beforep->next;
                }
                newnode->next = beforep->next;
                beforep->next = newnode;
            }
        }
        return (tree->next);
    }
    
    /*对霍夫曼树进行编码 */
    long Huffmancoding(linktree tree , int  &v , int &u)
    {
        int index = 0;
        char *code;
        linktree ptr = tree;
        code = (char *)malloc(10 * sizeof(char));/*此数组用于统计霍夫曼编码*/
        long ret = 0;
    
        if (ptr == NULL)
        {
            cout << "霍夫曼树是空的!" << endl;
            exit(0);
        }
        else
        {
            while (ptr->lchild&&ptr->rchild&&ptr->mark == 0)
            {
                while (ptr->lchild&&ptr->lchild->mark == 0)
                {
                    code[index++] = '0';
                    ptr = ptr->lchild;
                    if (!ptr->lchild&&!ptr->rchild)
                    {
                        ptr->mark = 1;
                        code[index] = '';
    
                        //计算信号长度
                        int temp = 0;
                        for (index = 0; code[index] != ''; index++)
                        {
                            if (code[index] == '0')
                                temp += u;
                            else if (code[index] == '1')
                                temp += v;
                        }//for
    
                         ret = ret + (temp * ptr->weight);
    
                        ptr = tree;
                        index = 0;
    
                    }//while
                }//while
    
                if (ptr->rchild&&ptr->rchild->mark == 0)
                {
                    ptr = ptr->rchild;
                    code[index++] = '1';
                }//if
    
                if (!ptr->lchild&&!ptr->rchild)
                {
                    ptr->mark = 1;
                    code[index++] = '';
    
                    //计算信号长度
                    int temp = 0;
                    for (index = 0; code[index] != ''; index++)
                    {
                        if (code[index] == '0')
                            temp += u;
                        else if (code[index] == '1')
                            temp += v;
                    }
    
                    ret += (temp * ptr->weight);
    
                    ptr = tree;
                    index = 0;
                }//if
    
                if (ptr->lchild->mark == 1 && ptr->rchild->mark == 1)
                {
                    ptr->mark = 1;
                    ptr = tree;
                    index = 0;
                }//if
            }//while
        }//else
    
        return ret;
    }
    
    
    /*释放霍夫曼树所占用的空间*/
    void deletenode(linktree tree)
    {
        linktree ptr = tree;
        if (ptr)
        {
            deletenode(ptr->lchild);
            deletenode(ptr->rchild);
            free(ptr);
        }
    }
    
    int main()
    {
        int n , u=0 , v=0;
        cin >> n;
        for (int i = 0; i < n; i++)
        {
            cin >> u >> v;
            char character[MAXLEN];
    
            linktree temp, ht, htree, ptr = NULL;
    
            cin >> character;
    
            temp = tidycharacter(character);
    
            ht = taxisnode(temp);
    
            htree = createHftree(ht);
    
            //得到发送时间最小长度
            cout << Huffmancoding(htree, u, v) << endl;
    
            //释放内存
            deletenode(htree);
        }//for
    
    
        system("pause");
    
        return 0;
    }
    
  • 相关阅读:
    ckplayer的Error #2033:Can not call javascript:ckstyle()解决
    C#中的参数关键字params
    c#中的可选参数和命名参数的使用
    c#中的dynamic类型
    c#中关于变量声明那么点事
    C# 自定义控件的一些文章和博客
    datatable,查询,排序,复制等操作
    HTML5 实现图像模糊算法
    FASTCGI程序,做个备份,以后用
    PHP的一些函数
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214861.html
Copyright © 2011-2022 走看看