首页 > 其他分享 >数据结构-单链表-详解-1

数据结构-单链表-详解-1

时间:2024-08-30 09:23:18浏览次数:13  
标签:结点 单链 cur 顺序 链表 详解 数据结构 指针

数据结构-单链表-详解-1

1.前言

数据结构-顺序表-详解中,我详细介绍了顺序表的实现,而顺序表也有一些缺点:

  • 中间,头部插入时,需整体挪动数据,效率低下。
  • 空间不够时扩容,有一定的消耗,也可能有一定空间浪费。

为了解决这些问题,引入了链表这一数据结构:

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

链表中,一个数据存入一个内存块,通过指针相连。这种结构使得插入和删除操作变得高效,因为只需要更新指针即可完成这些操作,而无需移动数据本身。
在功能上,顺序表与链表互补,相辅相成。
链表有很多种:

  • 单向或双向
  • 带头或不带
  • 循环或非循环

今天讲单链表。

与实现顺序表时类似,为了更好地组织代码,单链表在实现时建议放入三个文件中:
在这里插入图片描述

SList.hSList.ctest.c
头文件源文件测试文件
引用头文件,函数声明,宏定义,结构体定义具体的函数实现验证功能是否正确

.c文件都只需引用SeqList.h,可避免头文件的重复引用。
注:引用自建的头文件使用双引号

#include "SList.h"

关于命名
SList中的Ssingle
本文其他命名方式与顺序表一致,不再赘述。


2.结点

单链表一个内存块中需存储一个数据和一个指针。
对于多种类型的数据,使用结构体存储,在链表中,将这样的结构体称为结点。
SList.h

typedef int SLTDataType;
typedef struct SLTNode
{
	SLTDataType data;
	struct SLTNode* next;
}SListNode;

这段代码定义了一个名为SListNode的结构体类型,用于表示单链表中的结点。
每个结点包含一个数据成员data和一个指向下一个结点的指针next
需注意,关于next的定义,以下两种写法是错误的:

SLTNode* next;
SListNode* next;

第一种写法,在C语言中属于类型不完整。
第二种写法,在还没typedef时不能使用重定义类型。

3.打印

SList.h

void SListPrint(SListNode* phead);

SList.c

void SListPrint(SListNode* phead)
{
	SListNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

这段代码定义了一个名为SListPrint的函数,它接受一个指向链表头结点的指针作为参数。通过遍历链表,依次打印出每个结点的数据,最后输出NULL来表示链表的结尾。

其中,cur != NULL,即cur非0,为真。
可简化为:while(cur)

3.1关于断言

在顺序表中,函数的第一行一定是assert断言,而链表中有时不需要断言,为什么?

  • 顺序表中,传入函数的指针指向的是结构体,结构体存在内存的一块空间中,有具体地址;并且,顺序表为不为空,取决于结构体中size的大小,因此,指针不能为NULL,需要断言。
  • 单链表中,指向头结点的是指针,链表为空时指针可以为NULL,因此有时不需要断言。

3.2下一结点的找法

错误写法

cur++;

++可以找下一个位置吗?可以,但只能用在连续存放的情况下,如顺序表。
链表是非连续存放的,可以通过画图来理解:

物理结构

画出了实实在在数据内存中的变化,能帮助彻底理解。

在这里插入图片描述

逻辑结构

为了便于理解,形象化画出来的。

phead 结点1 cur 结点2 ... NULL

因此,使用cur = cur->next,可将下一结点的地址赋值给cur指针。


通过以上的介绍和代码实现,我们不仅了解了单链表的基本概念,还掌握了如何创建和打印单链表。希望这些内容能帮助你更好地理解单链表,并激发你进一步探索数据结构的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!

标签:结点,单链,cur,顺序,链表,详解,数据结构,指针
From: https://blog.csdn.net/2401_86587256/article/details/141499530

相关文章

  • 【AI绘画】Midjourney前置指令/blend、/info、/subscribe详解
    文章目录......
  • Makefile 基础与常用语法详解
    目录 一、引言二、Makefile基础概念1.目标、依赖和命令2.文件名和搜索路径3.执行顺序和依赖关系三、Makefile常用语法1.变量和宏定义2.自动变量3.模式规则 4.条件判断5.循环6.伪目标 四、Makefile实际应用示例五、总结 一、引言        在......
  • 数据结构:双向链表
    目录结构体创建链表插入链表头插法尾插法 遍历打印删除更新查找销毁结构体typedefintDataType;typedefstructnode{structnode*pPre;DataTypedata;structnode*pNext;}LinkNode;创建链表LinkNode*CreateDouList(){LinkNode......
  • 二. Spring Boot 中的 “依赖管理和自动配置” 详解透彻到底(附+详细代码流程)
    二.SpringBoot中的“依赖管理和自动配置”详解透彻到底(附+详细代码流程)@目录二.SpringBoot中的“依赖管理和自动配置”详解透彻到底(附+详细代码流程)1.如何理解“约定优于配置”2.SpringBoot依赖管理和自动配置2.1SpringBoot的依赖管理2.1.1什么是依赖管理......
  • 高阶数据结构-->图(中)
    前言:本文介绍了并查集的优化方案和图的2种基本的遍历方式。并查集的优化:普通的并查集可以看看我的这篇文章:高阶数据结构-->图(上)-CSDN博客先来谈谈为什么要优化?原先的并查集在面对一些极端情况时,查找根的效率会降低不少,举个例子:示例:此时当我们要查找5的根的时候,会不断往......
  • MySQL WAL机制详解
    目录:是什么undologRedoLog 与BinlogRedolog三种状态redolog 的持久化Binlog三种格式三种状态binlog 的持久化两者的联系状态Crash-Safe 能力三步提交的参数配置组提交优化" 三步提交"三步提交过程总结三个日志的比较(undo、redo、bin) ......
  • 数据结构与算法 第3天(栈和队列)
    栈和队列也是线性表,限制插入和删除的位置只能在端点栈(stack)后进先出LIFO表尾进入,表尾删除一、案例案例一:进制转换例子159转换成八进制159/8=19...719/8=2...32/8=0...2结果为237案例二:括号匹配的检验左括号先入栈,右括号有匹配的话与左括号一起出栈案例三:表......
  • 2023数据结构408程序题C语言
    如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。#include<stdio.h>#include<stdlib.h>//定义结构体数组S,其中的元......
  • C语言基础——函数详解
    目录 函数的概述1函数的概念2函数的意义 函数的定义和使用1函数的定义2函数的调用2.1在同一文件中函数定义后函数调用2.2在同一文件中函数定义前函数调用2.3调用其它文件中定义的函数2.3.1在函数调用文件中进行声明2.3.2在头文件中进行函数的声明 函......
  • Java——Stream 流的使用详解
    Stream 是一个可以用于操作集合、数组等数据源的API,主要进行数据的转换、筛选、聚合等操作这样做可以避免显式地使用迭代器或者循环来操作集合,提高代码的可读性和简洁性特点: 1、无存储性:是基于数据源的对象,本身不存储元素,而是通过管道将数据源元素传递给操作2......