首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

抽象数据类型(ADT)的有关问题

2012-04-13 
抽象数据类型(ADT)的问题list.hC/C++ code#ifndef LIST_H_#define LIST_H_enum Bool {False, True}/* 把B

抽象数据类型(ADT)的问题
list.h

C/C++ code
#ifndef LIST_H_#define LIST_H_enum Bool {False, True};    /* 把Bool定义为类型, False,True是他的值 *//* 特定于程序的声明 */#define TSIZE 45            /* 存放片名的数组大小 */struct film {    char title[TSIZE];    int rating;};/* 一般类型定义 */typedef struct film Item;typedef struct node{    Item item;    struct node * next;} Node;typedef Node * List; /* 函数原型                            *//* 操作:  初始化一个列表                    *//* 操作前:plist指向一个列表                    *//* 操作后:该列表被初始化为空列表                */void InitializeList(List * plist);/* 操作:  确定列表是否为空列表                    *//* 操作前:plist指向一个已初始化的列表                *//* 操作后:如果该列表为空则返回True;否则返回False            */Bool ListIsEmpty(const List * plist);/* 操作:  确定列表是否已满                    *//* 操作前:plist指向一个已初始化的列表                *//* 操作后:如果该列表已满则返回True;否则返回fales            */Bool ListIsFull(const List * plist);/* 操作:  确定列表中项目的个数                    *//* 操作前:plist指向一个已初始化的列表                *//* 操作后:返回该列表中项目的个数                */unsigned int ListItemCount(const List * plist);/* 操作:  在列表尾部添加一个项目                *//* 操作前:item是要被增加到列表的项目                *//*         plist指向一个已初始化的列表                *//* 操作后:如果可能的话,在列表末尾添加一个新项目            *//*         函数返回True;否则函数返回False            */Bool AddItem(Item item, List * plist);/* 操作:  把一个函数作用于列表中的每个项目            *//* 操作前:plist指向一个已初始化的列表                *//*         pfun指向一个函数,该函数接受                *//*         一个Item参数并且无返回值                    *//* 操作后:pfun指向的函数被作用到                *//*         列表的每个项目一次                    */void Traverse(const List * plist, void(* pfun)(Item item));/* 操作:  释放已分配的内存(如果有)                *//* 操作前:plist指向一个已初始化的列表                *//* 操作后:为该列表分配的内存已被释放                *//*         并且该列表被置为空列表                    */void EmptyTheList(List * plist);#endif


list.c
C/C++ code
#include <stdio.h>#include <stdlib.h>#include "list.h"/* 局部函数原型                */static void CopyToNode(Item item, Node * pnode);/* 接口函数                    *//* 把列表设置为空列表        */void InitializeList(List * plist){    *plist = NULL;}/* 如果列表为空则返回真        */Bool ListIsEmpty(const List * plist){    if(*plist == NULL)        return True;    else        return False;}/* 如果列表已满则返回真 */Bool ListIsFull(const List * plist){    Node * pt;    Bool full;    pt = (Node *)malloc(sizeof(Node));    if(pt == NULL)        full = True;    else        full = False;    free(pt);    return full;}/* 返回节点数 */unsigned int ListItemCount(const List * plist){    unsigned int count = 0;    Node * pnode = *plist;        /* 设置到列表的开始处 */    while(pnode != NULL)    {        ++count;        pnode = pnode->next;    /* 把l设置为下一个节点 */    }    return count;}/* 创建存放项目的节点,并把它添加到 *//* 有plist指向的列表(较慢的实现方法)尾部 */Bool AddItem(Item item, List * plist){    Node * pnew;    Node * scan = *plist;    pnew = (Node *)malloc(sizeof(Node));    if(pnew == NULL)        return False;            /* 失败时退出函数 */    CopyToNode(item, pnew);    pnew->next = NULL;    if(scan == NULL)            /* 空列表,因此把pnew */        *plist = pnew;            /* 放在列表头部          */    else    {        while(scan->next != NULL)            scan = scan->next;    /* 找到列表结尾           */        scan->next = pnew;        /* 把pnew添加到结尾处  */    }    return True;}/* 访问每个节点并对它们分别执行由pfun指向的函数 */void Traverse(const List * plist, void(* pfun)(Item item)){    Node * pnode = *plist;        /* 设置到列表的开始处 */        while(pnode != NULL)    {        (* pfun)(pnode->item);    /* 把函数作用于列表中的项目 */        pnode = pnode->next;    /* 前进到下一项 */    }}/* 释放malloc()分配的内存 *//* 把列表指针设置为NULL   */void EmptyTheList(List * plist){    Node * psave;    while(*plist != NULL)    {        psave = (*plist)->next;        /* 保存下一个节点的地址 */        free(*plist);                /* 释放当前节点            */        *plist = psave;                /* 前进到下一个节点        */    }}/* 局部函数定义 *//* 把一个项目复制到一个节点中 */static void CopyToNode(Item item, Node * pnode){    pnode->item = item;                /* 结构复制 */} 



films3.c
C/C++ code
#include <stdio.h>#include <stdlib.h>            /* 为exit()提供原型 */#include "list.h"            /* 定义List,Item    */void showmovies(Item item);int main(void){    List movies;         // 疑惑,这里不是等同struct node * movies吗    Item temp;           // 这个movies不是已经是一个指针了吗?    /* 初始化 */    InitializeList(&movies);  // 那这里为什么要用&movies?    if(ListIsFull(&movies))    {        fprintf(stderr, "No memory available! Bey!\n");        exit(EXIT_FAILURE);    }    /* 收集并存储 */    puts("Enter first movie title: ");    while(gets(temp.title) != NULL && temp.title[0] != '\0')    {        puts("Enter your rating (0-10): ");        scanf("%d", &temp.rating);        while(getchar() != '\n')            continue;        if(AddItem(temp, &movies) == False)        {            fprintf(stderr, "Problem allocating memory\n");            break;        }        if(ListIsFull(&movies))        {            puts("The list is now full.");            break;        }        puts("Enter next movie title (empty line to stop): ");    }    /* 显示 */    if(ListIsEmpty(&movies))        printf("No data entered.\n");    else    {        printf("Here is the movie list: \n");        Traverse(&movies, showmovies);    }    printf("You entered %d movies.\n", ListItemCount(&movies));    /* 清除 */    EmptyTheList(&movies);    printf("Bey!\n");    return 0;}void showmovies(Item item){    printf("Movie: %s Rating: %d\n", item.title,         item.rating);}


films3.c里我用//标出了不明白的地方,请各位说说,不是很明白啊

[解决办法]
typedef Node * List List是指针类型
void InitializeList(List * plist);这个函数的参数是指针的指针
所以movies传递给InitializeList必须加上&符号


[解决办法]
感觉你这代码写的挺有意思的!首先你的问题,你的函数原型是List *pList;面List本来就是指向一个结点的指针,所以List *pList,就是指向结点指针的指针,然后这样做的原因也很简单,因为指向链表的指针有可能会发生变化,所以就要这样子传递,当然还有一些其它的方法,另外你还专门写了一个ListIsFull,我还是第一次见到这样子写的,呵呵,感觉没有必要,另外有些地方可以改进,AddItem可以不用那样写的,

热点排行