C语言数据结构之单向链表详解分析

C语言数据结构之单向链表详解分析

什么是单向链表?

单向链表是一种常见的数据结构,它由一系列节点(或称单元)组成,每个节点都包含两个数据域:数据和指针。其中,数据用于存储具体的数据信息,指针则用于指向下一个节点。这样,一个链表就可以看做是由一个一个节点链接而成的数据结构。而单向链表中的指针只能指向下一个节点,因此被称为单向链表。

如何使用单向链表?

单向链表通常用于需要频繁插入、删除节点的场景,因为这种情况下使用数组等静态数据结构会导致效率低下。另外,链表还可以根据需求来灵活扩充大小,可以节省空间。

单向链表的实现

单向链表的实现主要包括链表的初始化、节点的插入、节点的删除、查找节点等功能。

链表的初始化

初始化需定义一个链表头结点,头节点的作用主要为了方便链表中节点的插入、删除等操作。

typedef struct node {
    int data; // 数据域
    struct node *next; // 指针域
} Node, *LinkList; 

LinkList InitList() {
    LinkList head = (LinkList)malloc(sizeof(Node)); // 动态分配头结点的内存空间
    head->next = NULL;
    return head; // 返回头结点
}

节点的插入

节点的插入需要根据插入位置创建新节点,然后将其连接到链表中。

void InsertNode(LinkList head, int pos, int elem) {
    Node *p = head;
    for (int i = 1; i < pos; i++) {
        if (p == NULL) return;
        p = p->next; // 找到需要插入的位置
    }
    Node *newNode = (Node *)malloc(sizeof(Node)); // 动态分配一个新节点
    newNode->data = elem;
    newNode->next = p->next; // 将新节点插入到链表中
    p->next = newNode;
}

节点的删除

删除节点同样需要找到节点位置,然后将其从链表中删除。

bool DeleteNode(LinkList head, int pos) {
    Node *p = head;
    for (int i = 1; i < pos; i++) {
        if (p == NULL) return false;
        p = p->next; // 找到需要删除的位置
    }
    if (p == NULL || p->next == NULL) return false;
    Node *temp = p->next; // 将节点从链表中删除
    p->next = temp->next;
    free(temp);
    return true;
}

查找节点

查找节点需要遍历整个链表,直到找到目标节点。

Node *GetNode(LinkList head, int pos) {
    Node *p = head;
    for (int i = 1; i <= pos; i++) {
        if (p == NULL || p->next == NULL) return NULL;
        p = p->next; // 遍历链表,直到找到目标节点
    }
    return p;
}

示例

示例1

现在我们需要用单向链表实现一个存储10个元素的列表,列表中元素分别为1, 3, 5,..., 19。可以通过以下方式实现:

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

typedef struct node {
    int data; // 数据域
    struct node *next; // 指针域
} Node, *LinkList; 

LinkList InitList() {
    LinkList head = (LinkList)malloc(sizeof(Node)); // 动态分配头结点的内存空间
    head->next = NULL;
    return head; // 返回头结点
}

void InsertNode(LinkList head, int pos, int elem) {
    Node *p = head;
    for (int i = 1; i < pos; i++) {
        if (p == NULL) return;
        p = p->next; // 找到需要插入的位置
    }
    Node *newNode = (Node *)malloc(sizeof(Node)); // 动态分配一个新节点
    newNode->data = elem;
    newNode->next = p->next; // 将新节点插入到链表中
    p->next = newNode;
}

void PrintList(LinkList head) {
    Node *p = head->next;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    LinkList head = InitList(); // 初始化链表
    for (int i = 1; i <= 10; i++) {
        InsertNode(head, i, 2 * i - 1); // 插入节点
    }
    PrintList(head); // 输出链表
    return 0;
}

输出结果:

1 3 5 7 9 11 13 15 17 19

示例2

现在我们需要实现一个存储学生信息的单向链表。每个学生信息包含学号和姓名两个字段。可以通过以下方式实现:

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

typedef struct student {
    int no; // 学号
    char name[50]; // 姓名
    struct student *next; // 指针域
} Student, *LinkList; 

LinkList InitList() {
    LinkList head = (LinkList)malloc(sizeof(Student)); // 动态分配头结点的内存空间
    head->next = NULL;
    return head; // 返回头结点
}

void InsertStudent(LinkList head, int pos, int no, char *name) {
    Student *p = head;
    for (int i = 1; i < pos; i++) {
        if (p == NULL) return;
        p = p->next; // 找到需要插入的位置
    }
    Student *newStudent = (Student *)malloc(sizeof(Student)); // 动态分配一个新学生
    newStudent->no = no;
    strcpy(newStudent->name, name);
    newStudent->next = p->next; // 将新学生插入到链表中
    p->next = newStudent;
}

void PrintStudent(LinkList head) {
    Student *p = head->next;
    while (p != NULL) {
        printf("学号:%d 姓名:%s\n", p->no, p->name);
        p = p->next;
    }
    printf("\n");
}

int main() {
    LinkList head = InitList(); // 初始化链表
    InsertStudent(head, 1, 101, "小明"); // 插入学生
    InsertStudent(head, 2, 102, "小红");
    InsertStudent(head, 3, 103, "小刚");
    PrintStudent(head); // 输出链表
    return 0;
}

输出结果:

学号:101 姓名:小明
学号:102 姓名:小红
学号:103 姓名:小刚

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之单向链表详解分析 - Python技术站

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

相关文章

  • webpack vue项目开发环境局域网访问方法

    Webpack 配置的 Vue 项目开发环境默认只能在本机进行访问。如果要在局域网内访问,则需要进行相应的配置。下面详细讲解 webpack vue 项目开发环境局域网访问方法的完整攻略。 1. 修改webpack配置 首先,我们需要修改 webpack 的配置文件,将 Host 配置为 0.0.0.0,表示接受所有的网络访问请求。 在 webpack.de…

    other 2023年6月27日
    00
  • win11环境变量在哪?Windows11环境变量设置方法

    下面是详细讲解“win11环境变量在哪?Windows11环境变量设置方法”的攻略: Windows11环境变量 环境变量的概念 在计算机中,环境变量是一种存储特定值的系统变量。在Windows中,这些变量包含了各种各样的系统信息,例如用户的个人文件夹位置、Windows的安装位置以及许多其他数据。由于这些信息是动态变化的,因此将它们存储在环境变量中可以让其…

    other 2023年6月27日
    00
  • c语言 树的基础知识(必看篇)

    C语言树的基础知识(必看篇) 什么是树 树是一种非线性数据结构,它由n个节点组成,这些节点通过边连接起来,形成一个分层结构。树的顶部节点称为根节点,没有子节点的节点称为叶子节点,其他节点则称为分支节点。 树的基本术语 节点(Node) 表示树中的元素,包含两个元素:数据和指向其子节点的指针。 边(Edge) 连接两个节点的线,表示节点之间的关系。 根节点(R…

    other 2023年6月27日
    00
  • teamfoundationserver基本功能

    Team Foundation Server基本功能 Team Foundation Server(TFS)是一种用于软件开发和应用生命周期管理的全面解决方案。它提供了一组关键功能,包括版本控制、质量管理、项目和团队协作、构建和部署自动化等等。在本文中,我们将着重介绍TFS的基本功能。 版本控制 TFS提供了一种有效的版本控制系统,可帮助软件团队协同开发。团…

    其他 2023年3月29日
    00
  • 路由器常见内存容量说识别

    路由器常见内存容量识别攻略 路由器常见内存容量识别是一项重要的技能,它可以帮助我们了解路由器的性能和适用场景。下面是一个详细的攻略,帮助你识别路由器的常见内存容量。 步骤一:查找路由器型号 首先,我们需要查找路由器的型号。通常,型号信息可以在路由器的外壳上或者设备的背面找到。型号信息通常以字母和数字的组合形式呈现,例如\”RT-AC68U\”。 步骤二:查找…

    other 2023年8月1日
    00
  • css父元素选择器

    什么是CSS父元素选择器? CSS父元素选择器是一种CSS选择器,它可以选择某个元素的父元素。使用CSS父元素选择器可以方便地对父元素进行样式设置,而不必为每个子元素单独设置样式。 如何使用CSS父元素选择器? CSS父元素选择器使用“>”符号来选择某个元素的直接父元素。以下是一个使用CSS父元素选择器的示例: <div class="…

    other 2023年5月7日
    00
  • 【精简系统教程】iOS8完美越狱后删除无用的iOS原生软件

    【精简系统教程】iOS8完美越狱后删除无用的iOS原生软件 一、前言 iOS原生应用虽然与日常工作息息相关,但很多时候我们并不需要每个应用,用不着的应用还会占用不少宝贵的设备储存空间。但通常情况下,我们不能像卸载第三方应用那样轻松删除原生应用,这个时候就需要一些小技巧了,本教程将介绍iOS8完美越狱后删除无用的iOS原生软件的方法。 二、步骤 首先确保你的设…

    other 2023年6月27日
    00
  • kibana下载与安装

    以下是关于Kibana下载与安装的完整攻略,包括Kibana的定义、下载和安装方法、示例说明和注意事项。 Kibana的定义 Kibana是一种用于视化和分析Elasticsearch数据的开源工具。它提供了一个用户友好的Web界面,可以帮助用户快速创建和共享动态仪表板、图表和地等数据可视化。 下载和安装方法 以下是在Windows操作系统上下载和安装Kib…

    other 2023年5月8日
    00
合作推广
合作推广
分享本页
返回顶部