数据结构上机实验学习体会

2017.11.7
今天阅读了cantjie的关于哈夫曼编码任务的程序中的header.h, list.c与count.c中的count_from_file函数
有如下认识:
1.首先在header.h中声明项目所需的预编译指令、库函数以及所需的数据结构和函数的声明。
2.在本任务中,需要
(1)定义每个结点的数据类型 listNode,其中有借点数据域单独的结构体 listData.
(2) 因为后续的哈夫曼编码中的建立哈夫曼树等操作都是基于链表的,于是需要一个listHead的数据类型,这种数据类型的head中存储链表的相关信息,包括length(文件中不同字符的数目)、cnt(字符数)、布尔型的duplicate_tag以判断字符是否重复,
而且在判断字符是否重复,以及最终统计文件总字符数的时候需要遍历整个链表,于是得定义一个遍历的标签traverse_tag(也是bool型)
头结点head中应包含head->next,head->curr,head->tail.
(3)基于链表的函数有
listHead*create_list(void) //创建一个新链表,并返回链表头
listHead*append_list(listHead *head,char ch[]) //如果新读入字符原先不存在,则用该函数创建新结点
listHead*foreach(listHead *head) //对链表进行循环,用以检查重复和最后统计频率
listHead *count_from_file(char filename[]) // 函数以统计文件中字符的频率和频数

2017.11.14
今天继续学习,试着写了读取字符的函数count_from_file(char filename[])

#include"header.h"

listHead *count_from_file(char filename[]){
    FILE* fp;
    listHead* head;
    listData* data;
    bool duplicate_tag;
    char ch[2];  //用两个字节来适应文档中会出现汉字的情况
    fp = fopen(filename, 'r');
    head = create();
    while (*ch = fgetc(fp) != EOF){
        if (ch[0] < 0)  //ch[0]<0代表该字符为汉字,则再读一位
        {
            ch[1] = fgetc(fp);
        }
        else { ch[1] = '\0'; }
        duplicate_tag = false;
        //判断是否重复
        while (data = foreach(head)){  //此处data循环指向链表中的结点,即foreach函数按次序返回链表中的结点的地址
            //如果两字符串相等,则频数+1
            //不能用strcmp(data->ch,ch)来比较,因为该函数会一直比较直到'\0'
            if (0 == memcmp(data->ch, ch, 2))
            {
                data->cnt++;
                duplicate_tag = true;
                head->traverseTag = false;
                break;
            }
            //如果该字符还没有出现,则调用append_list函数

        }
    }


}

}

2017.11.21
今天在写添加结点的函数listNode* append_list(listHead*head, char ch[])时,得到一些启发:
在写函数时,要注意边界条件,如分配空间要判断是否成功,对链表添加结点时判断链表长度状况:长度为零还是其他。
这里写代码片

猜你喜欢

转载自blog.csdn.net/han_xj/article/details/78470999