回 帖 发 新 帖 刷新版面

主题:[原创]压缩文件的问题,求救!!

/*========================================*/
              /*  课题[3]哈夫曼编码实现文件的压缩功能   */
              /*                                        */
              /*                                        */
              /*========================================*/

#include<stdio.h>                      //包含头文件
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<iostream.h>


#define MAX_SINGLECODE 10          //单个字符最大码长
#define MAX_STRING 10000            //要编码的字符串的最大长度
#define MAX_CODESTRING 50000       //产生的二进制码的最大长度
#define MAX_WORDS 1000                 //要编码的字符串中字符种数最大值
#define END_TREE 30000                 //树部分存储的结束符
#define PATH 50                    //路径的最大字符


                    /*======数据结构定义部分======*/

/*哈夫曼树结构定义,其中的next域用于链表的操作*/
typedef struct Huffmantree
{
    char ch;                    //字符部分
    int weight;                 //结点权值
    int    mark;                //标记是否加入树中
    struct Huffmantree *parent,*lchild,*rchild,*next;
}HTNode,*LinkTree;

/*****编码字典结构定义*****/
typedef struct                        //ch为字符值,code[]为该字符的哈夫曼编码
{
    char ch;                          //字符部分
    char code[MAX_SINGLECODE];        //编码部分
}CodeDictionary;

                     
                         /*======子函数======*/

/*===================压缩功能实现部分=====================*/

/*功能:读取.TXT文件并将其中的字符中保存到string[]中*/
void readFile(char *string)
{
    FILE *fp;
    int i;
    char ch;                                    //记录读入的字符
    char path[PATH];                        //文本文件的读路径

    cout<<"请输入要压缩的.txt文件地址:(无需扩展名)"<<endl;
    gets(path);
    if((fp=fopen(strcat(path,".txt"),"r"))==NULL) //只读方式打开一个文件
    {
        cout<<"\n路径不正确!\n"<<endl;
        getch();
        return;
    }

    ch=fgetc(fp);                     //循环将文件内的字符输入到数组string[]中
    for(i=0;ch!=EOF;i++)
    {
        string[i]=ch;
        ch=fgetc(fp);
    }
    string[i]='\0';                   //数组末尾加上结束标志'\o'
    fclose(fp);
}

回复列表 (共1个回复)

沙发



/*功能对string[]中的字符处理,将相同的舍去,并增加权值*/
LinkTree setWeight(char *string)
{
    int i=0;                                    //文件字符串下标
    LinkTree tree;                              //头指针
    LinkTree ptr,beforeptr;                     //创建指针与其前驱
    HTNode *node;
    
    if((tree=(LinkTree)malloc(sizeof(HTNode)))==NULL)//创建链表的头结点
        return NULL;                                 //内存不足
    tree->next=NULL;
    
    for(i=0;string[i]!='\0';i++)
    {    
        ptr=tree;
        beforeptr=tree;
        
        if((node=(HTNode *)malloc(sizeof(HTNode)))==NULL)
            return NULL;                              //建立新的结点
        node->next=NULL;
        node->parent=NULL;
        node->lchild=NULL;
        node->rchild=NULL;
        node->mark=0;
        node->ch=string[i];
        node->weight=1;
        
        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++;                    //将该结点的权加一  
                free(node);    
            }
            else                                //将新结点插入链表后
            {    
                node->next=beforeptr->next;
                beforeptr->next=node;
            }
        }
    }
    return tree;                                //返回头指针
}


/*功能:将链表中的含权字符按权的从小到大排列并输入到一链表*/
LinkTree sortNode(LinkTree tree)
{    
    LinkTree head;                                //头指针
    LinkTree ph,beforeph;                        //创建指针及其前驱
    LinkTree pt;
    
    if((head=(LinkTree)malloc(sizeof(HTNode)))==NULL)//创建新链表的头结点
        return NULL;
    head->next=NULL;
    
    ph=head;
    beforeph=head;
    
    while(tree->next)
    {    
        pt=tree->next;                            //取被操作链表的头结点
        tree->next=pt->next;
        pt->next=NULL;
        
        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;                                //返回排序后的头指针
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册