C语言实现单链表的基本功能详解

C语言实现单链表的基本功能详解

简介

单链表是一种常见的数据结构,由一系列的节点(Node)组成,每个节点包含数据和指向下一个节点的指针,最后一个节点的指针为NULL。C语言实现单链表需要掌握指针和动态内存分配的知识,具有一定难度。本文将详细讲解C语言实现单链表的基本功能。

基本结构

定义单链表结点的结构体,包括数据和指向下一个结点的指针,如下所示:

typedef struct node
{
    int data;
    struct node *next;
} Node;

该结构体定义了一个Node类型的节点,包含数据data和指向下一个节点的指针next。

定义头节点,头节点不存储数据,只用于表示单链表的开始。

Node *head = NULL;

head是一个指向Node类型的指针,初始值为NULL,表示链表为空。

基本功能

添加节点

添加节点是单链表最基本的操作之一,在单链表中,可以在头节点或者尾节点后面添加一个新节点。

在头节点后插入

在头节点后插入新节点,需要先创建一个新节点,然后将新节点的next指针指向head,再将head指向新节点。

void insertAtHead(int data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = head;
    head = newNode;
}

在尾节点后插入

在尾节点后插入新节点,需要先找到尾节点,然后创建新节点,将尾节点的next指向新节点,再将新节点的next指针设置为NULL。

void insertAtTail(int data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;

    if (head == NULL)   // 空链表,直接插入
    {
        head = newNode;
        return;
    }

    Node *p = head;
    while (p->next != NULL) 
    {
        p = p->next;
    }
    p->next = newNode;
}

删除节点

删除节点同样是单链表的基本操作之一,可以删除指定位置的节点,或者删除指定数值的节点。

删除指定位置节点

删除指定位置节点,需要先找到指定位置,然后修改前一个节点的next指针,使其指向被删除节点的下一个节点。

void deleteByPos(int pos)
{
    if (head == NULL)
    {
        printf("链表为空\n");
        return;
    }

    if (pos == 1)   // 删除头节点
    {
        Node *temp = head;
        head = head->next;
        free(temp);
        temp = NULL;
        return;
    }

    Node *p = head;
    int i = 1;
    while (p != NULL && i < pos - 1)  // 找到要删除节点的前一个节点
    {
        p = p->next;
        i++;
    }

    if (p == NULL || p->next == NULL)  // 要删除的节点不存在
    {
        printf("要删除的节点不存在\n");
        return;
    }

    Node *temp = p->next;
    p->next = temp->next;
    free(temp);
    temp = NULL;
}

删除指定数值节点

删除指定数值节点,需要遍历单链表,找到指定数值的节点,然后进行删除操作。

void deleteByData(int data)
{
    if (head == NULL)
    {
        printf("链表为空\n");
        return;
    }

    if (head->data == data)  // 删除头节点
    {
        Node *temp = head;
        head = head->next;
        free(temp);
        temp = NULL;
        return;
    }

    Node *p = head;
    while (p->next != NULL && p->next->data != data)
    {
        p = p->next;
    }

    if (p->next == NULL)  // 要删除的节点不存在
    {
        printf("要删除的节点不存在\n");
        return;
    }

    Node *temp = p->next;
    p->next = temp->next;
    free(temp);
    temp = NULL;
}

查找节点

查找节点可以按位置查找,也可以按数值查找。

按位置查找

按位置查找,需要遍历单链表,找到指定位置的节点。

Node *findByPos(int pos)
{
    if (head == NULL)
    {
        printf("链表为空\n");
        return NULL;
    }

    Node *p = head;
    int i = 1;
    while (p != NULL && i < pos)
    {
        p = p->next;
        i++;
    }

    if (p == NULL)  // 要查找的节点不存在
    {
        printf("要查找的节点不存在\n");
        return NULL;
    }

    return p;
}

按数值查找

按数值查找,同样需要遍历单链表,找到指定数值的节点。

Node *findByData(int data)
{
    if (head == NULL)
    {
        printf("链表为空\n");
        return NULL;
    }

    Node *p = head;
    while (p != NULL && p->data != data)
    {
        p = p->next;
    }

    if (p == NULL)  // 要查找的节点不存在
    {
        printf("要查找的节点不存在\n");
        return NULL;
    }

    return p;
}

示例说明

示例一:在头节点插入新节点

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

typedef struct node
{
    int data;
    struct node *next;
} Node;

Node *head = NULL;

void insertAtHead(int data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = head;
    head = newNode;
}

int main()
{
    insertAtHead(3);
    insertAtHead(2);
    insertAtHead(1);

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

    return 0;
}

输出结果:

1 2 3

示例二:在尾节点插入新节点

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

typedef struct node
{
    int data;
    struct node *next;
} Node;

Node *head = NULL;

void insertAtTail(int data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;

    if (head == NULL)
    {
        head = newNode;
        return;
    }

    Node *p = head;
    while (p->next != NULL)
    {
        p = p->next;
    }
    p->next = newNode;
}

int main()
{
    insertAtTail(1);
    insertAtTail(2);
    insertAtTail(3);

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

    return 0;
}

输出结果:

1 2 3

总结

本文主要讲解了C语言实现单链表的基本功能,包括添加节点、删除节点、查找节点等操作。需要掌握的知识点有指针和动态内存分配。单链表是一种非常常用的数据结构,掌握基本操作可以为后续数据结构和算法的学习打下基础。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现单链表的基本功能详解 - Python技术站

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

相关文章

  • arm编译器fromelf使用说明

    ARM编译器fromelf使用说明 fromelf是ARM编译器提供的一个命令行工具,用于将ARM二进制文件转换为其他格式,如ELF、COFF、HEX、BIN。本文将细讲解fromelf的使用方法及实例,并提供两个示例说明。 1. 安装fromelf fromelf是ARM编译器自的工具,因此无需单独安装。只需安装ARM编译器即可使用fromelf。 2. …

    other 2023年5月8日
    00
  • sql无效字符 执行sql语句报错解决方案

    SQL无效字符执行SQL语句报错的解决方案 当我们在使用SQL语句时,有时候会碰到SQL无效字符的问题,导致SQL语句无法执行。这篇文章主要介绍如何解决SQL无效字符问题。 1. 什么是SQL无效字符 SQL语句中的无效字符是指不符合SQL语法规范的字符,包括但不限于以下几种情况: 关键字拼写错误; 语法错误; SQL注入攻击; 2. 解决方案 我们可以通过…

    other 2023年6月26日
    00
  • 《C++ primer plus》读书笔记(一)

    下面是《C++ primer plus》读书笔记(一)的完整攻略。 《C++ primer plus》读书笔记(一) 简介 《C++ primer plus》作为一本C++入门级教材,深受广大读者喜爱。本读书笔记(一)主要分为三个部分:C++程序结构、标准输入输出和简单类型。在这些内容的学习中,我们将逐步了解C++基础语法和常用类型,打下扎实的基础,为我们后…

    other 2023年6月26日
    00
  • iOS逆向工程使用dumpdecrypted工具给App脱壳

    首先,需要明确一下什么是脱壳。在iOS系统中,应用程序通常会被加密以保护其代码不被人轻易地窃取。而脱壳就是指利用一些工具将被加密的应用程序解密,从而让人们能够对其代码进行分析和修改。 其中,dumpdecrypted就是一款常用的用于iOS逆向工程的工具,它可以帮助我们将被加密的应用程序进行解密操作。 下面,我们来具体讲解一下如何使用dumpdecrypte…

    other 2023年6月26日
    00
  • iOS开发之适配iOS10以及Xcode8

    iOS开发之适配iOS10以及Xcode8 简介 随着iOS 10的推出以及Xcode 8的正式发布,许多iOS开发者发现在新版本的开发环境中需要对项目进行一些适配工作才能确保应用程序在iOS 10上正常运行,本文将详细介绍如何适配iOS 10以及Xcode 8开发环境。 环境适配 在Xcode 8中,苹果引入了一些新特性以及变化,因此需要对开发环境进行一些…

    other 2023年6月26日
    00
  • JVM内存分配及String常用方法解析

    当然!下面是关于\”JVM内存分配及String常用方法解析\”的完整攻略: JVM内存分配及String常用方法解析 JVM内存分配 在Java中,JVM会自动管理内存分配。以下是JVM中常见的内存区域: 堆(Heap):用于存储对象实例和数组。堆内存由垃圾回收器自动管理,对象的创建和销毁都在堆中进行。 栈(Stack):用于存储局部变量和方法调用。栈内存…

    other 2023年8月19日
    00
  • 打造博客园(cnblogs)超级自定义界面

    打造博客园(cnblogs)超级自定义界面的攻略主要包括以下几个步骤: 1. 创建博客园账号 首先需要去博客园官网上注册一个账号(https://www.cnblogs.com),如果已经有账号可以直接登录。 2. 选择主题 博客园的自定义主题是基于.NET平台开发的,可以根据自己的喜好选择主题,如果不喜欢可以上网下载别人开发的主题。 3. 修改配置文件 打…

    other 2023年6月25日
    00
  • 魔兽世界7.2.5狂暴战怎么堆属性 wow7.25狂暴战配装属性优先级攻略

    魔兽世界7.2.5狂暴战怎么堆属性 简介 在魔兽世界7.2.5版本中,狂暴战是一个强大的近战职业,它能够产生巨大的伤害和持久的输出。在这篇攻略中,我们将为您介绍如何正确的堆狂暴战的属性。 属性优先级 狂暴战的属性优先级为:暴击 > 急速 > 硬度 > 巨龙怒吼 > 精通 > 全能 暴击(Crit) 暴击是狂暴战的最重要的属性之一…

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