C LinkList Demo

Published on with 0 views and 0 comments

  

list.h head 头类,定义接口

 1// 如果没有定义 LIST_H_宏
 2#ifndef LIST_H_
 3// 定义LIST_H宏
 4#define LIST_H_
 5// 布尔
 6#include <stdbool.h>
 7// 标题长度
 8#define TSIZE 45
 9// 电影 结构体
10struct film {
11  // 电影名称
12  char title[TSIZE];
13  // 评分
14  int rating;
15};
16// 将 struct film 用 Item类型代替
17typedef struct film Item;
18// 将 struct node 使用 Node代替
19typedef struct node{
20  Item item;
21  struct node *next;
22} Node;
23// 链表结构和Node类相同
24typedef Node *List;
25// 初始化链表
26void InitalizeList(List *plist);
27// 链表是否为空
28bool ListIsEmpty(const List *plist);
29// 是否还可以创建新的next节点
30bool ListIsFull(const List *plist);
31// 所有节点数量
32unsigned int ListItemCount(const List *plist);
33// 新增一个节点
34bool AddItem(Item item, List *plist);
35void Traverse(const List *plist, void (*pfun)(Item item));
36// 释放所有节点
37void EmptyTheList(List *plist);
38
39#endif
40

list.c 对应 list.h 提供实现类

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include "list.h"
  4
  5static void CopyToNode(Item item, Node *pnode);
  6// 初始化链表
  7void InitalizeList(List *plist)
  8{ 
  9    // 直接指向空
 10    *plist = NULL;
 11}
 12// 判断链表是否为空
 13bool ListIsEmpty(const List *plist)
 14{
 15   // 看链表是否指向空就可以了
 16    return *plist == NULL ? true : false;
 17}
 18// 是否还可以新增节点
 19bool ListIsFull(const List *plist)
 20{
 21    Node *pt;
 22    bool full;
 23  // 为新节点分配一个内存,分的出来就代表可以新增
 24    pt = (Node *)malloc(sizeof(Node));
 25    if (pt == NULL)
 26    {
 27        full = true;
 28    }
 29    else
 30    {
 31        full = false;
 32    }
 33    free(pt);
 34    return full;
 35}
 36// 查询所有节点计算总量
 37unsigned int ListItemCount(const List *plist)
 38{
 39    unsigned int count = 0;
 40    Node *pnode = *plist;
 41    while (pnode != NULL)
 42    {
 43        ++count;
 44        // 进入下一个节点
 45        pnode = pnode->next;
 46    }
 47    return count;
 48}
 49// 添加元素
 50bool AddItem(Item item, List *plist)
 51{
 52    // 新节点
 53    Node *pnew;
 54    // 传入链表
 55    Node *scan = *plist;
 56   // 为新节点分配内存
 57    pnew = (Node *)malloc(sizeof(Node));
 58   // 如果新节点分配不出来就返回false
 59    if (pnew == NULL)
 60    {
 61        return false;
 62    }
 63   // 把item内容拷贝到节点的item属性中
 64    CopyToNode(item, pnew);
 65   // 新节点的下一个节点设置为空
 66    pnew->next = NULL;
 67   // 如果传入的链表为空链表,则直接让指针指向新节点
 68    if (scan == NULL)
 69    {
 70        *plist = pnew;
 71    }
 72   // 否则追加至末尾
 73    else
 74    {
 75        while (scan->next != NULL)
 76        {
 77            scan = scan->next;
 78        }
 79        scan->next = pnew;
 80    }
 81    return true;
 82}
 83// 接受一个链表,一个void函数,函数参数为Item类型
 84void Traverse(const List *plist, void (*pfun)(Item item))
 85{
 86    Node *pnode = *plist;
 87    // 挨个调用函数
 88    while (pnode != NULL)
 89    {
 90        (*pfun)(pnode->item);
 91        pnode = pnode->next;
 92    }
 93}
 94// 释放所有链表内存
 95void EmptyTheList(List *plist)
 96{
 97    Node *psave;
 98    while (*plist != NULL)
 99    {
100        psave = (*plist)->next;
101        free(*plist);
102        *plist = psave;
103    }
104}
105
106static void CopyToNode(Item item, Node *pnode)
107{
108    pnode->item = item;
109}
110

movie.c 入口函数

 1// 引入头文件
 2#include "list.h"
 3#include <stdio.h>
 4#include <string.h>
 5#include <stdlib.h>
 6
 7void showmovies(Item item);
 8char *s_gets(char *st, int n);
 9
10int main(void)
11{
12 // 声明一个链表
13  List movies;
14// 声明一个临时节点
15  Item temp;
16// 初始化链表
17  InitalizeList(&movies);
18 // 查看链表是否可以继续创建节点
19  if (ListIsFull(&movies))
20  {
21    fprintf(stderr, "No memory available! Bye!\n");
22    exit(EOF);
23  }
24  puts("Enter first movie title");
25// 循环一直输入除非不在进行输入
26  while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '\0')
27  {
28    puts("Enter your rating <0-10>");
29 // 将输入的数字存入 temp节点的rating属性上
30    scanf("%d", &temp.rating);
31 // 如果获取到的不是空行
32    while (getchar() != '\n')
33    {
34      continue;
35    }
36// 将temp加入链表
37    if (AddItem(temp, &movies) == false)
38    {
39      fprintf(stderr, "Problem allocating memory.\n");
40      break;
41    }
42    if (ListIsFull(&movies))
43    {
44      fprintf(stderr, "List is full.\n");
45      break;
46    }
47    puts("Enter next movie title (empty line to stop);");
48  };
49  if (ListIsEmpty(&movies))
50  {
51    printf("No data entered.");
52  }
53  else
54  {
55    printf("Here is the movie list :\n");
56// 传入一个 链表内存地址 和 含有一个Item参数的函数地址
57    Traverse(&movies, showmovies);
58  }
59  printf("You entered %d movies\n", ListItemCount(&movies));
60  EmptyTheList(&movies);
61  printf("Bye!\n");
62
63  return 0;
64}
65
66void showmovies(Item item)
67{
68  printf("Movie %s Rating %d\n", item.title, item.rating);
69}
70
71char *s_gets(char *st, int n)
72{
73  char *ret_val;
74  char *find;
75  ret_val = fgets(st, n, stdin);
76  if (ret_val)
77  {
78    find = strchr(st, '\n');
79    if (find)
80      *find = '\0';
81    else
82      while (getchar() != '\n')
83        continue;
84  }
85  return ret_val;
86}

标题:C LinkList Demo
作者:fe
地址:https://blog.eiyouhe.com/articles/2019/12/22/1576996926974.html