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

文章目录

1-11题

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

例题12

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

c 复制代码
struct ListNode {
    int value;
    struct ListNode* next;
};

请实现以下几个函数:

初始化链表:将链表头节点初始化为 NULL。

c 复制代码
void initList(struct ListNode** head);

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

c 复制代码
void insertNode(struct ListNode** head, int value);

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

c 复制代码
void deleteNode(struct ListNode** head, int value);

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

c 复制代码
void printList(struct ListNode* head);

测试用例

请在下面的代码框架下编写代码

c 复制代码
#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答案

答案一

c 复制代码
#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 作为参数。通过遍历链表,每次输出当前节点的值,然后将指针指向下一个节点,直到链表末尾。

答案二

c 复制代码
#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 函数:

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

相关推荐
ajsbxi几秒前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Ocean☾1 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking1 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
顶呱呱程序9 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
&岁月不待人&16 分钟前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
StayInLove19 分钟前
G1垃圾回收器日志详解
java·开发语言
TeYiToKu21 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws24 分钟前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然040224 分钟前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
无尽的大道27 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化