C语言链表—实战篇

注:以下示例摘自《C Prime Plus》第17章。

本文为《C语言链表—基础篇》的姊妹篇,主要完成链表的实现。

回顾一下程序需求:

编写一个程序,让用户输入一年内看过的所有电影。要存储每部电影的各种信息,如片名、发行年份、导演、主演、影片种类等等。建议使用一个结构存储每部电影,一个数组存储一年内看过的电影。为了简单起见,我们规定结构中只有两个成员:片名和等级(1~10)。

1. 主程序 


#include <stdio.h>
#include <stdlib.h> /* 提供 malloc 原型 */
#include <string.h> /* 提供 strcpy 原型 */

#define MAX_SIZE 5
#define MAX_NAME_LEN 50

struct film {
    char name[MAX_NAME_LEN];
    int rating;
    struct film * next_ptr;
};

char * s_gets(char * st, int n);

int main(){
    struct film * head = NULL;
    struct film * pre, * curr;
    int i = 0;
    char input[MAX_NAME_LEN];

    puts("Enter first film title:");

    /* 收集和存储链表 */
    while( s_gets(input, MAX_NAME_LEN) != NULL && input[0] != '\0'){
        curr = (struct film *) malloc(sizeof(struct film));
        
        if (head == NULL) /* 第一个结构 */
            head = curr;
        else              /* 后续结构 */
            pre->next_ptr = curr;

        curr->next_ptr = NULL;
        strcpy(curr->name, input);
        puts("enter your rating <0-10>: ");
        scanf("%d", &curr->rating);
        while (getchar() != '\n'){
            continue;
        }
        puts("enter next Film name (empty line to stop):");
        pre = curr;
    }

    if(head == NULL)
        printf("No data entered \n");
    else    
        printf("Here is the movie list: \n");

    /* 显示链表 */
    curr = head;
    while (curr != NULL)
    {
        printf("Film: %s, Rating %d \n", curr->name, curr->rating);
        curr = curr->next_ptr;
    }
    
    /* 释放链表 */
    curr = head;
    while(curr != NULL){
        free(curr);
        curr = curr->next_ptr;
    }
    puts("Happy solstice!"); 

    return 0;
}

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)
            *find = '\0';
        else
            while(getchar() != '\n')
                continue;
    }
    return ret_val;
}

2. 程序解读

下边我们针对程序的结构进行解读。程序主要分为三部分:创建链表,显示链表和释放链表。

2.1 创建链表

主要有以下三个步骤:

(1)使用 malloc() 分配空间。

curr = (struct film *) malloc(sizeof(struct film));

(2)储存结构的地址。

链表的第一个结构的地址应该储存在指针变量 head 中。随后每个结构的地址应存储在其前一个结构的 next_ptr 成员中。

if (head == NULL)
    head = curr;
else 
    pre->next_ptr = curr;

为当前结构成员设置合适的值,尤其是把 next_ptr 成员设置成 NULL,表明当前结构是链表的最后一个结构。

curr->next_ptr = NULL;

(3)把用户输入信息拷贝到结构中。

strcpy(curr->name, input);
puts("enter your rating <0-10>: ");
scanf("%d", &curr->rating);

2.2 显示链表 

显示链表从设置一个指向第一个结构的指针开始。由于头指针(head)已经指向链表中第一个结构,可以将头指针(head)赋值给当前指针(curr):

curr = head;

通过一个 while 循环将链表中的全部值打印出来。在循环中,通过指针取出当前结构的 name 和 rating 成员,同时将 next_ptr 赋值给 curr。如果此循环,直到链表的最后一个机构中 next_ptr 的值为 NULL, while 循环将结束。

while (curr != NULL){
    printf("Film: %s, Rating %d \n", curr->name, curr->rating);
    curr = curr->next_ptr;
}

遍历链表时,为何不直接使用 head 指针,而要重新创建一个新指针(current)?如果直接使用 head 会改变 head 的值,程序便找不到电影链表的第一个结构了。

2.3 释放链表

 在许多环境中,程序结束时都会自动释放 malloc( ) 分配的内存。但是,最好还是成对调用 malloc( ) 和 free( )。

curr = head;
while(curr != NULL){
    free(curr);
    curr = curr->next_ptr;
}

程序运行结果:

总结

如此,一个简单的链表便实现了,但是有很多不足。比如:程序没有检查 malloc( ) 是否成功请求到内存,也不支持删除链表中的项。后边,可以通过建立抽象,来实现一个通用性更强的链表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值