C语言编写链表的初始化、插入、删除、打印操作

news/2024/6/18 21:27:23 标签: c语言, 链表, 算法, 开发语言, 学习, 数据结构

文章目录

  • 1-11题
  • 例题12
  • 例题12答案
    • 答案一
    • 答案二

1-11题

C语言基础例题1-3题-指针篇
C语言基础例题4-5题-二维数组篇
C语言基础例题6-7题-结构体篇
C语言基础例题8-9题-大作业篇
C语言基础例题10-11题-字符串、指针篇

例题12

编写一个 C 语言程序,实现一个简单的链表结构。链表节点的定义如下:

struct ListNode {
    int value;
    struct ListNode* next;
};

请实现以下几个函数:
初始化链表:将链表头节点初始化为 NULL。

void initList(struct ListNode** head);

插入节点:在链表末尾插入一个节点,节点的值为 value。

void insertNode(struct ListNode** head, int value);

删除节点:删除链表中第一个值等于 value 的节点,假设链表中不存在重复的值。

void deleteNode(struct ListNode** head, int value);

打印链表:按顺序打印链表中的所有节点的值。

void printList(struct ListNode* head);

测试用例
请在下面的代码框架下编写代码

#include <stdio.h>
struct ListNode
{
    int value;
    struct ListNode *next;
};
void initList(struct ListNode **head);
void insertNode(struct ListNode **head, int value);
void deleteNode(struct ListNode **head, int value);
void printList(struct ListNode *head);
int main(void)
{
    struct ListNode *head = NULL;
    initList(&head);
    insertNode(&head, 5);
    insertNode(&head, 10);
    insertNode(&head, 15);
    deleteNode(&head, 10); // 删除值为 10 的节点
    deleteNode(&head, 20); // 不存在值为 20 的节点,不进行删除操作
    printList(head);
    return 0;
}
void initList(struct ListNode **head)
{
}
void insertNode(struct ListNode **head, int value)
{
}
void deleteNode(struct ListNode **head, int value)
{
}
void printList(struct ListNode *head)
{
}

插入节点和删除节点后的打印结果应为:
5 15

例题12答案

答案一

#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
    int value;
    struct ListNode *next;
};
void initList(struct ListNode **head);
void insertNode(struct ListNode **head, int value);
void deleteNode(struct ListNode **head, int value);
void printList(struct ListNode *head);
int main(void)
{
    struct ListNode *head = NULL;
    initList(&head);
    insertNode(&head, 5);
    insertNode(&head, 10);
    insertNode(&head, 15);
    deleteNode(&head, 10); // 删除值为 10 的节点
    deleteNode(&head, 20); // 不存在值为 20 的节点,不进行删除操作
    printList(head);
    return 0;
}
void initList(struct ListNode **head)
{
    *head = NULL;
}
void insertNode(struct ListNode **head, int value)
{
    struct ListNode *node = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *current = *head;
    node->value = value;
    node->next = NULL;
    if (!(*head))
        *head = node;
    else
    {
        while (current->next)
            current = current->next;
        current->next = node;
    }
}
void deleteNode(struct ListNode **head, int value)
{
    struct ListNode *prev = NULL, *current = *head;
    while (current && current->value != value)
    {
        prev = current;
        current = current->next;
    }
    if (current)
    {
        if (prev)
        {
            prev->next = current->next;
            free(current);
        }
        else
        {
            current = *head;
            *head = (*head)->next;
            free(current);
        }
    }
}
void printList(struct ListNode *head)
{
    while (head != NULL)
    {
        printf("%d ", head->value);
        head = head->next;
    }
}

initList 函数:
这个函数接受一个指向指针的指针 head 的参数。通过将 head 指向 NULL,表示空链表

insertNode 函数:
这个函数接受一个指向指针的指针 head 和一个整型值 value 的参数。首先,使用 malloc 动态分配一个新的节点,并设置节点的值为传入的整数值 value。然后,检查链表是否为空,若为空,则将新节点赋值给 head;否则,遍历链表直到找到链表末尾,将新节点链接到链表末尾。

deleteNode 函数:
这个函数接受一个指向指针的指针 head 和一个整型值 value 的参数。首先,使用两个指针 prev 和 current 来遍历链表,同时查找目标值 value 所在的节点。若找到该节点,则进行删除操作:如果 prev 不为空,则将 prev->next 指向 current->next,然后释放 current 节点的内存;如果 prev 为空,说明要删除的节点是头节点,将 *head 指向 (*head)->next,然后释放 current 节点的内存。

printList 函数:
这个函数接受一个指向链表头节点的指针 head 作为参数。通过遍历链表,每次输出当前节点的值,然后将指针指向下一个节点,直到链表末尾。

答案二

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

struct ListNode
{
    int value;
    struct ListNode *next;
};

void initList(struct ListNode **head);
void insertNode(struct ListNode **head, int value);
void deleteNode(struct ListNode **head, int value);
void printList(struct ListNode *head);

int main(void)
{
    struct ListNode *head = NULL;
    initList(&head);
    insertNode(&head, 5);
    insertNode(&head, 10);
    insertNode(&head, 15);
    deleteNode(&head, 10); // 删除值为 10 的节点
    deleteNode(&head, 20); // 不存在值为 20 的节点,不进行删除操作
    printList(head);
    return 0;
}

void initList(struct ListNode **head)
{
    *head = NULL;
}

void insertNode(struct ListNode **head, int value)
{
    struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
    newNode->value = value;
    newNode->next = NULL;

    if (*head == NULL)
    {
        *head = newNode;
    }
    else
    {
        struct ListNode *temp = *head;
        while (temp->next != NULL)
        {
            temp = temp->next;
        }
        temp->next = newNode;
    }
}

void deleteNode(struct ListNode **head, int value)
{
    struct ListNode *current = *head;
    struct ListNode *previous = NULL;

    while (current != NULL && current->value != value)
    {
        previous = current;
        current = current->next;
    }

    if (current == NULL)
    {
        // 没找到值为 value 的节点
        return;
    }

    if (previous == NULL)
    {
        // 要删除的节点是头节点
        *head = current->next;
    }
    else
    {
        previous->next = current->next;
    }

    free(current);
}

void printList(struct ListNode *head)
{
    struct ListNode *current = head;
    while (current != NULL)
    {
        printf("%d ", current->value);
        current = current->next;
    }
    printf("\n");
}

initList 函数
接受一个指向指针的指针作为参数,将其所指向的指针设置为 NULL,表示空链表

insertNode 函数:
接受一个指向指针的指针和一个整型值作为参数。首先,通过 malloc 动态分配一个新的节点,并设置节点的值为传入的整数值。然后,检查链表是否为空,如果为空则将新节点直接设置为头节点,如果不为空则遍历链表直到找到链表尾部,将新节点链接到尾部。

deleteNode 函数:
这个函数接受一个指向指针的指针和一个整型值作为参数。首先,使用两个指针 current 和 previous 来遍历链表找到需要删除的节点,然后通过修改指针的指向来删除节点,并使用 free 释放节点所占用的内存空间。

printList 函数:
这个函数接受一个指向链表头节点的指针作为参数,然后通过遍历链表并输出每个节点的值来实现打印功能。


http://www.niftyadmin.cn/n/5170821.html

相关文章

JRebel热部署——效率提升100倍(程序员工具必备)

1. 下载JRebel 2.激活程序 这里推荐一个免费获取jrebel激活服务器地址和激活邮箱的地址:点击进入 进入网站之后就可以获取到激活链接和邮箱 点击进入激活 复制过去激活就可以 然后就可以看到激活成功了 3.如何使用 代码修改后&#xff0c;直接CtrlShitF9 即可重新启动 4…

合成数据加速机器视觉学习

虽然机器学习在基于视觉的自动化中的应用正在增长&#xff0c;但许多行业都面临着挑战&#xff0c;并难以在其计算机视觉应用中实施它。这在很大程度上是由于需要收集许多图像&#xff0c;以及与准确注释这些图像中的不同产品相关的挑战。 该领域的最新趋势之一是利用合成数据…

银河的c++课堂——[NOIP1999 普及组] 导弹拦截

目录 题目描述 输入格式 输出格式 输入输出样例 题目描述 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。某天&…

你的代码有bug

作为程序员&#xff0c;我们时常会收到这样的反馈&#xff1a;“你的代码有bug”。当面临这种情况时&#xff0c;我们可能会感到受伤和失落。然而&#xff0c;我们应该认识到&#xff0c;代码问题是一种常见现象&#xff0c;无论是谁都可能遇到。通过接受批评和建议&#xff0c…

如何解决多线程下的共享对象问题?分布式系统又该如何应对?

嗨&#xff0c;各位小米粉丝们&#xff01;欢迎来到小米带你飞的微信公众号&#xff01;今天我们要聊的话题可是程序员们都头疼的大问题哦——多线程情况下的对象共用问题&#xff0c;以及在分布式系统中的应对策略&#xff01;小米要给大家详细解读一下&#xff0c;让你的技术…

python opencv 读取文件夹下所有MP4文件并解析成jpg图像

你可以使用Python的OpenCV库来读取文件夹中的所有MP4文件&#xff0c;并将其解析为JPG图像。以下是一个示例代码&#xff0c;演示了如何实现这个功能&#xff0c;并设置解析间隔为3帧&#xff1a; import os import cv2def extract_frames(input_folder, output_folder, inter…

nodejs收集指定目录下图片,检索当前项目是否被引用

const fs require("fs"); const node_path require("path"); /*** 数组去重* param {*} arr*/ const distinct (arr) > {return Array.from(new Set(arr)); };class cleanImg {constructor({imgFilePath, // 存放图片文件夹的路径srcFilePath, // sr…

【docker:容器提交成镜像】

容器创建部分请看&#xff1a;点击此处查看我的另一篇文章 容器提交为镜像 docker commit -a "sinwa lee" -m "首页变化" mynginx lxhnginx:1.0docker run -d -p 88:80 --name lxhnginx lxhnginx:1.0为啥没有变啊&#xff0c;首页&#xff1f; 镜像打包 …