algorithm6 2022-04-23 17:22 采纳率: 76.2%
浏览 38
已结题

C语言学习,链表的实现

我在编写下面程序时:
film.c

//使用抽象数据类型(ADT)风格的链表
//与list.c一起编译
#include <stdio.h>
#include <stdlib.h>  //提供exit()的原型
#include <string.h>
#include "list.h"  //定义List、Item
void showmovies(Item item);
char *s_gets(char *st, int n);
int main(void)
{
   List movies;
   Item temp;
   //初始化
   InitializeList(&movies);
   if (ListIsFull(&movies))
   {
      fprintf(stderr, "No memory available! Bye!\n");
      exit(1);
   }

   //获取用户输入并存储
   puts("Enter first movie title:");
   while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '\0')
   {
      puts("Enter your rating <0-10>:");
      scanf("%d", &temp.rating);
      while (getchar() != '\n')
         continue;
      if(AddItem(temp, &movies) == 0)
      {
         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. ");
   else
   {
      printf("Here is the movie list:\n");
      Traverse(&movies, showmovies);
   }
   printf("You entered %d movies.\n", ListItemCount(&movies));

   //清理
   EmptyTheList(&movies);
   printf("Bye!\n");

   return 0;
}

void showmovies(Item item)
{
   printf("Movie: %s Rating: %d\n", item.title, item.rating);
}

char *s_gets(char *st, int n)
{
   char *ret_val;
   char *find;

   ret_val = fgets(st, n, stdin);
   if (ret_val)
   {
      find = strchr(st, '\n');  //查找换行符
      if(find)  //如果地址不是NULL
         *find='\0';  //在此处放置一个空字符
      else
         while (getchar() != '\n')
            continue;  //处理输入行的剩余内容
   }
   return ret_val;
}

list.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

//局部函数的原型
static void CopyToNode(Item item,List *plist);

//接口函数
//把链表置空
void InitializeList(List *plist)
{
   plist=(List *)malloc(sizeof(List));
   if (plist != NULL)(*plist).items=0;
   else exit(EXIT_FAILURE);
}

//如果链表为空,返回1
int ListIsEmpty(const List *plist)
{
   //使用items成员直接判别链表是否已为空
   if ((*plist).items==0)
      return 1;
   else
      return 0;
}

//如果链表已满,返回1
int ListIsFull(const List *plist)
{
   int full;
   if ((*plist).items==MAXSIZE)
      full=1;
   else
      full=0;
   return full;
}

//返回节点数量
unsigned int ListItemCount(const List *plist)
{
   return (unsigned int)(* plist).items;
}

//创建存储项的节点
int AddItem(Item item, List *plist)
{
   if (ListIsFull(plist))
      return 0;
   //对于静态列表,需要判断链表是否已满
   CopyToNode(item, plist);
   plist->items++;
   //复制节点进行数的下一个元素,下标表示为(*plist).items++

   return 1;
}

void Traverse(const List *plist, void (*pfun)(Item item))
{
   int i=0;

   while (i<(*plist).items)
      (*pfun)((*plist).enteries[i++]);
   //按照数组的形式遍历所有节点
}

void EmptyTheList(List *plist)
{
   (*plist).items=0;
}

static void CopyToNode(Item item, List *plist)
{
   strcpy((*plist).enteries[(*plist).items-1].title,item.title);
   (*plist).enteries[(*plist).items-1].rating = item.rating;
   //该函数需要根据Item结构体进行修改,以上是针对struct film修改的例子
   //(*plist).enteries[(*plist).items-1] = item;
}

list.h

//接口头文件,简单链表类型的头文件
#ifndef LIST_H_
#define LIST_H_

//特定程序的声明

#define TSIZE 45  //存储电影名的数组大小
struct film
{
   char title[TSIZE];
   int rating;
};

//一般类型定义

typedef struct film Item;

typedef struct node
{
   Item item;
   struct node *next;
} Node;

#define MAXSIZE 100
typedef struct list
{
   Item enteries[MAXSIZE];  //项数组
   int items;  //列表中项的个数
} List;

//函数原型

//操作:初始化一个链表
//前提条件:plist指向一个链表
//后置条件:链表初始化为空
void InitializeList(List *plist);

//操作:确定链表是否为空,plist指向一个已初始化的链表
//后置条件:如果链表为空,该函数返回true;否则返回false
int ListIsEmpty(const List *plist);

//操作:确定链表是否已满,plist指向一个已初始化的链表
//后置条件:如果链表已满,该函数返回true;否则返回false
int ListIsFull(const List *plist);

//操作:确定链表中的项数,plist指向一个已初始化的链表
//后置条件:该函数返回链表中的项数
unsigned int ListItemCount(const List *plist);

//操作:在链表的末尾添加项
//前提条件:item是一个待添加至链表的项,plist指向一个已初始化的链表
//后置条件:如果可以,该函数在链表末尾添加一个项,且返回ture,否则返回false
int AddItem(Item item, List *plist);

//操作:把函数作用于链表中的每一项
//plist指向一个已初始化的链表
//pfun指向一个函数,该函数接受一个Item类型的参数,且无返回值
//后置条件:pfun指向的函数作用于链表中的每一项一次
void Traverse(const List *plist, void(*pfun)(Item item));

//操作:释放已分配的内存(如果有的话)
//plist指向一个已初始化的链表
//后置条件:释放了为链表分配的所有内存,链表设置为空
void EmptyTheList(List *plist);

#endif

运行结果如下

img


请问是什么问题?应该如何修改

  • 写回答

3条回答 默认 最新

  • 关注

    你typedef struct list 中这样
    Item enteries[MAXSIZE]; //项数组
    int items; //列表中项的个数
    定义是顺序表的方式, 不是链表啊

    你顺序表和链表弄混了吧

    你题目的解答代码如下:

    void InitializeList(List *plist)
    {
       //plist=(List *)malloc(sizeof(List));//plist已经初始化了,不需要再创建
       if (plist != NULL)(*plist).items=0;
       else exit(EXIT_FAILURE);
    
    }
    static void CopyToNode(Item item, List *plist)
    {
       strcpy((*plist).enteries[(*plist).items].title,item.title);//去掉-1
       (*plist).enteries[(*plist).items].rating = item.rating;//去掉-1
       //该函数需要根据Item结构体进行修改,以上是针对struct film修改的例子
       //(*plist).enteries[(*plist).items-1] = item;
    }
    
    

    img

    如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月1日
  • 已采纳回答 4月23日
  • 创建了问题 4月23日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效