C 语言中的ADT 中的一个列表的问题

#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
//#include <stdbool.h>
#define bool int
#define false 0
#define true 1

//特定于程序的声明
#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,否则返回false
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_H_INCLUDED




List.c


static void CopyToNode(Item item,Node * pnode);
void InitializeList(List * plist)
{
    *plist = NULL;
}



//函数原型
//操作:确定列表是否为空列表
//操作前:plist指向一个列表
//操作后:如果该列表为空返回true,否则返回false
bool ListIsEmpty (const List * plist)
{
    if( *plist == NULL)
        return true;
    else
        return false;
}
//函数原型
//操作:确定列表是否已满
//操作前:plist指向一个已初始化的列表
//操作后:如果该列表为满返回true,否则返回false
bool ListIsFull (const List * plist)
{
    Node * pf;
    pf = (List) malloc(sizeof(Node));
 //   if(pf)
//    return true;
//    else//不能这样写,因为pf != NULL ,也不能说明了pf为真。
//    return false;
    if(pf == NULL)
    return true;
    else
    return false;
}
//函数原型
//操作:确定列表中项目的个数
//操作前:plist指向一个已初始化的列表
//操作后:返回该列表中项目的个数
unsigned int ListItemCount(const List * plist)
{
    Node * pnode;
    pnode = *plist;
    unsigned int count=0;
    while( pnode != NULL)
    {
        count++;
        pnode = pnode->next;
    }
    return count;
}

//函数原型
//操作:在列表尾部添加一个项目
//操作前:item是要被增加到列表的项目
//          plist指向一个已初始化的列表
//操作后:如果可能的话,在列表尾部添加一个新项目,
//          函数返回true,否则返回false
bool AddItem (Item item,List * plist)
{
    Node * pnode;
    Node * scan;//用来扫描
    scan = *plist;
    pnode = (List)malloc( sizeof(Node));
    if(pnode == NULL)
    {
        //free(pnode);
        return false;
    }

    CopyToNode(item,pnode);
    pnode->next = NULL;
    if(scan == NULL)
    {
        *plist = pnode;//好像问题就在这了
        //scan = pnode;
    }
    else
    {
        while(scan->next != NULL)////这才是问题所在,如果写成了scan != NULL ,那么导致输出的时候只能输出一个。第一天调的我都快放弃了,第二天才终于调试成了。


        scan = scan->next;//找到了plist的 末尾了。
        scan = pnode;
    }
    return true;
}
//函数原型
//操作:把函数作用于列表中的每一个节点的操作
//操作前:plist指向一个已初始化的列表
//        pfun指向一个函数,该函数接受
//        一个Item参数并且无返回值
//操作后:pfun指向的函数被作用到列表中的每一个项目一次
void Traverse (const List *plist,void (* pfun) (Item item))
{
    Node * pnode;
    pnode = *plist;
    while( pnode != NULL )
    {
        (*pfun)(pnode->item);
        pnode = pnode->next;
    }
}

//函数原型
//操作:释放已分配的内存
//操作前:plist指向一个已初始化的列表
//操作后:为该列表分配的内存以释放,并且该列表被置为空列表
void EmptyTheList(List * plist)
{
    List pnode,prev;
    pnode = * plist;
    while( pnode != NULL)
    {
        prev = pnode->next;
        free(pnode);
        pnode = prev;//这个地方是我错的地方。当时写成了pnode = prev->next ,程序直接崩溃了
    }
}

void CopyToNode(Item item,Node * pnode)
{
    pnode->item = item;
}




main.c

#include <stdio.h>
#include <stdlib.h>
#include "list.h"//这在CB中时包含“list.h”,在VC中包含"list.c"

void showmovies(Item item);
int main(void)
{
    List movise;
    Item temp;
    InitializeList(&movise);
    if(ListIsFull(&movise))
    {
        fprintf(stderr,"列表已满safa!");
        exit(1);
    }
    printf("输入电影的名字:\n");
    while(gets(temp.title) != NULL && temp.title[0] != '\0')
    {
        puts("输入电影的级别:");
        scanf("%d",&temp.rating);
        while(getchar() != '\n')
        continue;
        if( !AddItem(temp,&movise) )
        {
            printf("内存已满!\n");
            break;
        }
        if(ListIsFull(&movise))
        {
            printf("列表已满!");
            break;
        }
        printf("输入电影的名字:\n");
    }

    printf("节点的个数为:%d\n",ListItemCount(&movise));
    //显示
    if(ListIsEmpty(&movise))
    {
        printf("没有电影!\n");
    }
    else
    {
        printf("这是电影的列表:\n");
        Traverse(&movise,showmovies);
    }

    EmptyTheList(&movise);
    return 0;
}
void showmovies(Item item)
{
    printf("title : %s rating : %d\n",item.title,item.rating);
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值