当前位置: 首页 > news >正文

数据结构——单链表1

1. 单链表

1.1 概念与结构

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

1.1.1 结点

  • 与顺序表不同的是,链表里的每节都是独立申请下来的空间,我们称之为“节点/结点”
  • 节点的组成部分主要有两个部分组成:当前节点要保存的数据(数据域)和保存下一个节点的地址(指针域)
  • 链表中每个节点都是独立申请的,(需要插入数据时才去申请一块节点的空间),需要指针变量来保存下一个节点的位置才可以从当前的节点找到下一个节点。

1.1.2 链表的性质

  • 链表结构在逻辑上时连续的,在物理结构上不一定是连续的
  • 节点一般是从堆上申请的
  • 从堆上申请来的空间,是按照一定的策略来分配的,每次申请的空间可能是连续的,也可能是不连续的

每个节点对应的结构体代码:

typedef int SLTDataType;
//定义链表节点的结构
typedef struct SListNode
{SLTDataType  data;       //节点数据struct SListNode* next;  //下一个节点的地址
}SLTNode;

1.1.3 链表的打印

//单链表的打印
void SLTPrint(SLTNode* phead) {SLTNode* pcur = phead;while (pcur){printf("%d -> ",pcur->data);pcur = pcur->next;}printf("NULL\n");
}

1.2 实现单链表

SList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//定义单链表就是定义节点,因为单链表是由节点组成的,所以定义单链表就是定义节点
typedef int SLTDataType;
//定义链表节点的结构
typedef struct SListNode
{SLTDataType  data;struct SListNode* next;
}SLTNode;//单链表的打印
void SLTPrint(SLTNode* phead);//单链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);//单链表的头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);//单链表的尾删
void SLTPopBack(SLTNode** pphead);
SList.c
#include"SList.h"//单链表的打印
void SLTPrint(SLTNode* phead) {SLTNode* pcur = phead;while (pcur != NULL){printf("%d -> ",pcur->data);pcur = pcur->next;}printf("NULL\n");
}//新节点的申请
SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));//申请新节点这里传的应该是节点类型而不是数据类型//单链表:每次插入一个节点时,需要分配一个节点(结构体)的内存,因此使用 `sizeof(节点类型)`。//顺序表:在扩容时,需要为多个数据元素分配一块连续的内存(即数组),因此使用 `元素个数 * sizeof(数据类型)`。if (node == NULL){perror("malloc fail!\n");exit(1);}node->data= x;node->next = NULL;return node;
}//单链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x) {//单链表为空assert(pphead);//SLTNode* Tail = *pphead; 不能在这里定义Tail 因为这里的Tail为空,后面循环中的Tail->next 就会报错,不会进入循环当中SLTNode* newnode = SLTBuyNode(x);if (*pphead == NULL){*pphead = newnode;}else {//单链表不为空,找尾节点,插入新节点SLTNode* Tail = *pphead;while (Tail->next != NULL){Tail = Tail->next;}//跳出循环,插入新节点Tail->next = newnode;//newnode->next = NULL; 不需要写是因为,newnode在初始化的时候就已经置为NULL了}
}//单链表的头插
void SLTPushFront(SLTNode** pphead, SLTDataType x) 
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}//单链表尾删
void SLTPopBack(SLTNode** pphead)
{assert(pphead);//只有一个节点的情况if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}SLTNode* Tail = *pphead;SLTNode* prev = NULL;while (Tail->next){prev = Tail;Tail = Tail->next;}//跳出循环prev->next = NULL;free(Tail);Tail = NULL;
}

后续还有其它的单链表的实现哦~~~

http://www.dtcms.com/a/306983.html

相关文章:

  • 【WRF-Chem】EDGAR 排放数据处理:分部门合并转化为二进制(Python全代码)
  • RAG实战指南 Day 27:端到端评估框架实现
  • CSS-in-JS 动态主题切换与首屏渲染优化
  • 1.5.Vue v-for 和 指令修饰符
  • COZE 开源,新一代 AI Agent 本地部署一条龙
  • Excel文件解析
  • OpenWrt Network configuration
  • 百度统计在哪里添加网站?
  • Linux系统启动不受未挂载硬盘影响的解决方案
  • Windows系统使用命令生成文件夹下项目目录树(文件结构树)的两种高效方法
  • 深度学习-丢弃法 Dropout
  • C语言基础11——结构体1
  • Qt Quick 动画与过渡效果
  • QT中QTableView+Model+Delegate实现一个demo
  • TikTok 视频审核模型:用逻辑回归找出特殊类型的视频
  • 全栈:SSH和SSM和Springboot mybatisplus有什么区别?
  • 以ros的docker镜像为例,探讨docker镜像的使用
  • 力扣刷题日常(7-8)
  • 【Arch-Linux,hyprland】常用配置-已实验成功指令大全(自用)(持续更新)
  • 如何保证数据库的持久性与一致性:从 Linux 磁盘缓存策略到 MySQL 的设计
  • 执业药师证识别技术:医药健康生态中发挥愈发关键的作用
  • 微软:科技领域的创新巨头
  • Sleeping Cup 论坛:连接开发者与创新的桥梁
  • 隧道COVI检测器的用处
  • [SKE]使用OpenSSL库实现AES、SM4、DES、RSA、3DES_EDE和3DES_EEE算法的加解密验证
  • SringBoot入门
  • Linux启动防火墙提示提示 Active: failed (Result: timeout)
  • Golang 指针与引用深度解析:对比 C/C++ 的内存管理哲学
  • Jupyter Notebook安装使用
  • Javascript对象合并