当前位置:首页 > C语言
线性表之无头结点的单向链表实验
来源:靑龍一笑的博客  作者:靑龍一笑  发布时间:2022-10-06 09:26:08  点击量:154  评论:0

    无头结点的单向链表的实现如下:

1、linklist.h 文件

/*
 * 线性表的链式存储结构(无头结点的单向链表)
 */
#ifndef LINKLIST_H__
#define LINKLIST_H__

// 宏定义
#define NAMESIZE 32

/*
 * 单向链表结构
 * 学生信息
 */
typedef struct stuinfo_st {
    int id; // 学号
    char name[NAMESIZE]; // 姓名
    int chinese; // 语文
    int math; // 数学
    int english; // 英语
}stuinfo;

/*
 * 单向链表结构
 */
typedef struct node_st {
    struct stuinfo_st data; // 数据结点
    struct node_st *next; // 指向下一个结点的指针
}linklist;

/*
 * 从链表头部往单向链表中插入数据
 */
int linklist_insert(linklist **, stuinfo *);

/*
 * 从单向链表的头部删除数据
 */
int linklist_delete(linklist **);

/*
 * 在单向链表中根据 ID 查找数据
 */
stuinfo * linklist_find(linklist *, int);

/*
 * 遍历单向链表
 */
void linklist_display(linklist *);

/*
 * 销毁单向链表
 * 释放单向链表所占内存
 */
void linklist_destroy(linklist *);

#endif

2、linklist.c 文件

#include <stdio.h>
#include <stdlib.h>

#include "linklist.h"

/*
 * 从链表头部往单向链表中插入数据
 */
int linklist_insert(linklist **ptr, stuinfo *data) {
    linklist *node; // 要插入数据的结点
    node = malloc(sizeof(*node));
    if (node == NULL) {
        return -1;
    }

    // 给结点赋值
    node->data = *data;
    // 将插入的结点指向链表的头部
    node->next = *ptr;
    // 将链表的头部改为插入的结点
    *ptr = node;

    // 成功插入
    return 0;
}

/*
 * 从单向链表的头部删除数据
 */
int linklist_delete(linklist **ptr) {
    linklist *node; // 要删除的结点
    
    if (*ptr == NULL) {
        // 空链表
        return -1;
    }

    // 将要删除的结点指向到链表的头部
    node = *ptr;
    // 将链表的头部指向到链表的第二个结点
    *ptr = (*ptr)->next;
    // 释放要删除结点所占内存
    free(node);
    // 将要删除结点指向为 NULL
    node = NULL;

    // 删除成功
    return 0;
}

/*
 * 在单向链表中根据 ID 查找数据
 */
stuinfo * linklist_find(linklist *ptr, int id) {
    linklist *node = ptr; // 当前结点
    while (node != NULL) {
        if (node->data.id == id) {
            // 找到数据
            return &node->data;
        }
        node = node->next;
    }

    // 找不到数据
    return NULL;
}

/*
 * 遍历单向链表
 */
void linklist_display(linklist *ptr) {
    linklist *node = ptr; // 当前结点
    while (node != NULL) {
        printf("%d %s %d %d %d\n", node->data.id, node->data.name, node->data.chinese, node->data.math, node->data.english);
        node = node->next;
    }

    return; // 无返回值
}

/*
 * 销毁单向链表
 * 释放单向链表所占内存
 */
void linklist_destroy(linklist *ptr) {
    linklist *node; // 要释放的结点

    if (ptr == NULL) {
        // 空链表
        return; // 无返回值
    }

    // 将要释放的结点指向到链表的头部
    node = ptr;
    while (node != NULL) {
        // 将链表的头部指向到当前要释放结点的下一个结点
        ptr = node->next;
        // 释放当前要释放结点所占内存
        free(node);
        // 将要释放的结点指向到当前链表的头部
        node = ptr;
    }

    return; // 无返回值
}

3、main.c 文件

#include <stdio.h>
#include <stdlib.h>

#include "linklist.h"

int main() {
    int i; // 循环索引值
    int ret; // 返回状态值

    linklist *list = NULL;
    stuinfo stu_st, *stu_ptr; // 操作中的学生信息
    int id = 3; // 要查找的学号

    /* 从链表头部往单向链表中插入 7 条随机数据 */
    for (i = 0; i < 7; i++) {
        stu_st.id = i; // 学号
        snprintf(stu_st.name, NAMESIZE, "stu%d", i); // 姓名
        stu_st.chinese = rand() % 100; // 语文
        stu_st.math = rand() % 100; // 数学
        stu_st.english = rand() % 100; // 英语

        ret = linklist_insert(&list, &stu_st);
        if (ret != 0) {
            fprintf(stderr, "数据插入失败!\n");
            exit(1);
        }
    }

    /* 遍历单向链表 */
    printf("链表中的学生信息:\n");
    linklist_display(list);

    /* 从单向链表的头部删除数据 */
    linklist_delete(&list);

    /* 遍历单向链表 */
    printf("\n链表中的学生信息:\n");
    linklist_display(list);
    printf("\n");

    stu_ptr = linklist_find(list, id);
    if (stu_ptr == NULL) {
        printf("没有找到任何数据!\n");
    } else {
        printf("%d %s %d %d %d\n", stu_ptr->id, stu_ptr->name, stu_ptr->chinese, stu_ptr->math, stu_ptr->english);
    }

    /* 销毁单向链表 */
    linklist_destroy(list);

    exit(0);
}

4、Makefile 文件

OBJS=main.o linklist.o
CC=gcc
CFLAGS+=-c -Wall -g
linklist:$(OBJS)
    $(CC) $^ -o $@
%.o:%.c
    $(CC) $^ $(CFLAGS) -o $@
clean:
    $(RM) *.o linklist -r

    执行效果:

root@RicenOS:~# make
gcc main.c -c -Wall -g -o main.o
gcc linklist.c -c -Wall -g -o linklist.o
gcc main.o linklist.o -o linklist
root@RicenOS:~# ./linklist
链表中的学生信息:
6 stu6 72 36 11
5 stu5 26 40 26
4 stu4 90 59 63
3 stu3 21 62 27
2 stu2 86 92 49
1 stu1 15 93 35
0 stu0 83 86 77

链表中的学生信息:
5 stu5 26 40 26
4 stu4 90 59 63
3 stu3 21 62 27
2 stu2 86 92 49
1 stu1 15 93 35
0 stu0 83 86 77

3 stu3 21 62 27
版权所有 © 2005-2023 靑龍一笑的博客  Powered by C.S.Ricen
Copyright © 2005-2023 by www.ricensoftwares.com.cn  All Rights Reserved.

欢迎光临本站,这里是靑龍一笑的博客。

因资金匮乏,本站已迁到国外的免费空间,可能导致本站的访问速度较慢,由此给您带来的不便,敬请谅解。

您可以通过下方的“支持本站建设”链接,给本站提供资金支持。

Free Web Hosting