​​​​​​​C语言实现单链表基本操作方法

下面是C语言实现单链表基本操作方法的完整攻略:

1. 定义单链表结构体

首先,需要定义一个单链表结构体,来描述节点的信息。结构体应该包含两个部分:数据域和指针域。数据域存储节点的值,指针域存储指向下一个节点的指针。

struct ListNode {
    int val;                // 数据域,此处数据类型为 int
    struct ListNode *next;  // 指针域,指向下一个节点
};

2. 添加节点

添加节点是单链表的最基本操作。我们需要定义一个函数来实现添加节点的功能。

首先,我们需要创建一个新节点,并为它分配内存空间。然后,根据需求将新节点插入到链表中,这需要找到要插入的位置,即要插入节点的前一个节点。最后,将新节点插入到链表中,并调整前一个节点和后一个节点的指针。

void insertNode(struct ListNode **head, int val) {
    // 创建新节点,并为其分配内存空间
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;

    // 特判链表为空的情况
    if (*head == NULL) {
        *head = newNode;
        return;
    }

    // 找到要插入的位置,即要插入节点的前一个节点
    struct ListNode* prev = NULL;
    struct ListNode* curr = *head;
    while (curr && curr->val < val) {
        prev = curr;
        curr = curr->next;
    }

    // 将新节点插入到链表中
    if (prev == NULL) {
        // 如果要插入到链表头部
        newNode->next = *head;
        *head = newNode;
    } else {
        // 如果要插入到链表中间或尾部
        newNode->next = prev->next;
        prev->next = newNode;
    }
}

上述函数中,使用了一个双重指针的技巧,用来修改头结点。具体实现过程如下:

struct ListNode* head = NULL;
...
insertNode(&head, 3);

3. 删除节点

删除节点是单链表的另一个基本操作。我们也需要定义一个函数来实现删除节点的功能。

在删除节点之前,我们需要首先找到要删除的节点,即要删除节点的前一个节点。然后,将前一个节点的指针指向要删除节点的下一个节点,再将要删除节点的空间释放。

void deleteNode(struct ListNode **head, int val) {
    // 特判链表为空的情况
    if (*head == NULL) {
        return;
    }

    // 特判要删除的节点为头结点的情况
    if ((*head)->val == val) {
        struct ListNode* temp = *head;
        *head = (*head)->next;
        free(temp);
        return;
    }

    // 找到要删除的节点,即要删除节点的前一个节点
    struct ListNode* prev = NULL;
    struct ListNode* curr = *head;
    while (curr && curr->val != val) {
        prev = curr;
        curr = curr->next;
    }

    // 删除节点,并释放空间
    if (curr) {
        prev->next = curr->next;
        free(curr);
    }
}

上述函数中也使用了双重指针的技巧。

示例说明

下面通过两个示例来说明如何使用上述函数操作单链表。

示例1:添加节点

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

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

void insertNode(struct ListNode **head, int val) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    struct ListNode* prev = NULL;
    struct ListNode* curr = *head;
    while (curr && curr->val < val) {
        prev = curr;
        curr = curr->next;
    }
    if (prev == NULL) {
        newNode->next = *head;
        *head = newNode;
    } else {
        newNode->next = prev->next;
        prev->next = newNode;
    }
}

int main() {
    struct ListNode* head = NULL;
    insertNode(&head, 3);
    insertNode(&head, 1);
    insertNode(&head, 2);
    insertNode(&head, 4);
    insertNode(&head, 5);
    struct ListNode* curr = head;
    while (curr) {
        printf("%d ", curr->val);
        curr = curr->next;
    }
    return 0;
}

输出结果为:1 2 3 4 5。

示例2:删除节点

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

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

void insertNode(struct ListNode **head, int val) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    struct ListNode* prev = NULL;
    struct ListNode* curr = *head;
    while (curr && curr->val < val) {
        prev = curr;
        curr = curr->next;
    }
    if (prev == NULL) {
        newNode->next = *head;
        *head = newNode;
    } else {
        newNode->next = prev->next;
        prev->next = newNode;
    }
}

void deleteNode(struct ListNode **head, int val) {
    if (*head == NULL) {
        return;
    }
    if ((*head)->val == val) {
        struct ListNode* temp = *head;
        *head = (*head)->next;
        free(temp);
        return;
    }
    struct ListNode* prev = NULL;
    struct ListNode* curr = *head;
    while (curr && curr->val != val) {
        prev = curr;
        curr = curr->next;
    }
    if (curr) {
        prev->next = curr->next;
        free(curr);
    }
}

int main() {
    struct ListNode* head = NULL;
    insertNode(&head, 3);
    insertNode(&head, 1);
    insertNode(&head, 2);
    insertNode(&head, 4);
    insertNode(&head, 5);
    deleteNode(&head, 3);
    deleteNode(&head, 1);
    struct ListNode* curr = head;
    while (curr) {
        printf("%d ", curr->val);
        curr = curr->next;
    }
    return 0;
}

输出结果为:2 4 5。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:​​​​​​​C语言实现单链表基本操作方法 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • C语言的isatty函数和ttyname函数以及sendmsg函数用法

    C语言是一种广泛使用的编程语言,涉及到很多系统底层的 API,而 isatty 函数、ttyname 函数以及 sendmsg 函数也是这其中的一部分。 isatty 函数 isatty 函数用于判断一个文件描述符是否是终端设备。其原型如下: int isatty(int fd); 其中,fd 为文件描述符,返回值表示是否是终端设备,是返回 1,否则返回 0…

    other 2023年6月27日
    00
  • 详解iOS应用开发中的ARC内存管理方式

    详解iOS应用开发中的ARC内存管理方式 什么是ARC ARC就是自动引用计数(Automatic Reference Counting)技术。在ARC技术出现之前,Objective-C开发者需要手动管理内存,需要在合适的时机手动增加或减少引用计数。ARC技术可以自动地在合适的时机增加或减少对对象的引用计数,从而简化了内存管理的工作。ARC技术是在编译时完…

    other 2023年6月26日
    00
  • iOS获取当前app的设备名称和版本号等内容

    以下是关于“iOS 获取当前 App 的设备名称和版本号等内容”的完整攻略,包含了两个示例说明。 获取设备名称 要获取当前设备的名称,可以使用以下代码: let 设备名称 = … UIDevice.current.name print(\"设备名称:\\(设备名称)\") 在这个示例中,我们使用了 UIDevice.current.n…

    other 2023年8月2日
    00
  • python 读取DICOM头文件的实例

    Python 读取 DICOM 头文件是医学图像处理领域的重要任务之一,下面将为大家详细讲解 Python 读取 DICOM 头文件的实例攻略。 1. 安装 pydicom 库 pydicom 是一个十分流行的 Python DICOM 库,可以用于读取、解析和处理 DICOM 文件。需要先安装该库才能进行后续的操作。 pip install pydicom…

    other 2023年6月27日
    00
  • docker mysql启动时执行初始化sql

    想要在docker中启动MySQL时自动执行初始化sql文件,可以通过以下步骤来实现: 1. 创建一个目录用于存放初始化文件 我们首先需要创建一个目录,用于存放我们的初始化sql脚本文件。 $ mkdir db_init_sql 2. 编写初始化sql脚本文件 在创建的目录下,我们需要创建一个或多个初始化sql脚本文件。这些sql文件包含了我们要在MySQL…

    other 2023年6月20日
    00
  • vue多次打包后出现浏览器缓存的问题及解决

    针对“vue多次打包后出现浏览器缓存的问题及解决”这个问题,我们可以采取以下两种方案: 方案一:添加hash 每次打包时,为打包的静态资源文件添加hash,这样即使文件内容不变,文件名字也会发生变化,避免浏览器缓存问题。 在vue.config.js配置文件中设置filenameHashing: true。 module.exports = { filena…

    other 2023年6月27日
    00
  • tor(洋葱头)torbrowser

    当然,我可以为您提供有关“Tor(洋葱头)浏览器”的完整攻略,以下是详细说明: 什么是Tor(洋葱头)浏览器? Tor(洋葱头)浏览器是一种基于浏览器的匿名浏览器,它使用Tor网络来隐藏用户的IP地址和浏览行为。Tor网络是一种由志愿者运行匿名网络,它通过将用户的网络流量路由到多个节点来隐藏用户的IP地址和浏览行为。 Tor(洋葱头)浏览器的安装步骤 以下是…

    other 2023年5月7日
    00
  • 微信公众平台通用接口api指南

    微信公众平台通用接口api指南 微信公众平台是一个常用的社交平台,许多企业和个人都在上面拥有自己的公众号,来进行推广和营销。为了更好地与用户互动,许多公众号都会接入微信公众平台提供的通用接口API。 API介绍 微信公众平台通用接口API是一套基于HTTP/HTTPS协议的接口,可用于进行微信公众号的开发和功能增强。API集成了许多有用的功能,例如自定义菜单…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部