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

数据结构---顺序表之单链表

1.链表的概念

链表是一种逻辑上是线性的,但物理结构不一定是线性的数据结构,它通过链表中的指针链接次序实现的

链表的存储空间是我们通过动态内存开辟的内存空间,所以他们的地址可能是连续的也可能不是连续的

2.链表的分类

1.单向或者双向

2.带头或者不带头

3.循环或者不循环

虽然链表有这么多种类,单我们常用的就只有两种:

                                               单向不带头不循环链表(单链表)

                                                   双向带头循环链表(双链表)

3.单链表的实现

SList.h

// 1、无头+单向+非循环链表增删查改实现
typedef int SLTDateType;
typedef struct SListNode
{SLTDateType data;struct SListNode* next;
}SListNode;
// 动态申请一个结点
SListNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode* pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode* pos);

SList.c

//为什么这里要用二级指针?
//因为我们的头结点是一个结构体指针,我们可能会改变头结点,所以我们需要传结构体地址的地址// 动态申请一个结点
SListNode* BuySListNode(SLTDateType x) {SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));if (NewNode == NULL) {return 0;}NewNode->next = NULL;NewNode->data = x;return NewNode;
}
// 单链表打印
void SListPrint(SListNode* plist) {SListNode* pcur = plist;while (pcur) {printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x) {assert(pplist);SListNode* NewNode = BuySListNode(x);//如果链表为NULL,头结点就是NewNodeif (*pplist == NULL) {*pplist = NewNode;return;}//链表不为NULL,找到尾节点插入SListNode* pcur = *pplist;while (pcur->next) {pcur = pcur->next;}pcur->next = NewNode;
}
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x) {assert(pplist);SListNode* NewNode = BuySListNode(x);SListNode* pcur = *pplist;NewNode->next = pcur;*pplist = NewNode;
}
// 单链表的尾删
void SListPopBack(SListNode** pplist) {assert(pplist);//链表为NULL不能执行删除assert(*pplist);//如果链表只有1个节点if ((*pplist)->next == NULL) {free(*pplist);*pplist = NULL;return;}SListNode* pcur = *pplist;SListNode* prev = NULL;while (pcur->next) {prev = pcur;pcur = pcur->next;}prev->next = pcur->next;free(pcur);pcur = NULL;
}
// 单链表头删
void SListPopFront(SListNode** pplist) {assert(pplist);assert(*pplist);SListNode* pcur = *pplist;*pplist = pcur->next;free(pcur);pcur = NULL;}
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x) {assert(plist);SListNode* pcur = plist;while (pcur) {if (pcur->data == x) {return pcur;}pcur = pcur->next;}//未找到返回NULLreturn NULL;
}
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
//因为单链表的节点只能找后继结点,不能找前驱
void SListInsertAfter(SListNode* pos, SLTDateType x) {assert(pos);SListNode* NewNode = BuySListNode(x);NewNode->next = pos->next;pos->next = NewNode;
}
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
// 如果链表存在多个节点,pos节点之前的节点就会丢失,造成内存泄露
void SListEraseAfter(SListNode* pos) {assert(pos);assert(pos->next);SListNode* DeleNode = pos->next;pos->next = DeleNode->next;free(DeleNode);DeleNode = NULL;
}


http://www.mrgr.cn/news/35132.html

相关文章:

  • LLMs之Code:Github Spark的简介、安装和使用方法、案例应用之详细攻略
  • Python并发编程入门:使用concurrent.futures与asyncio
  • PICO+Unity MR空间锚点
  • python opencv3
  • Vue.js 高质量翻页功能的完整开发指南
  • 游戏引擎学习第六天
  • openEuler普通用户su root时Permission denied
  • 视频生成技术分享
  • 深度学习技术在流体力学中的应用与实操培训【1/3理论课程2/3实操课程】
  • 408算法题leetcode--第14天
  • FastStone Capture屏幕长截图软件注册码
  • Paper 0 | Visual Instruction Tuning
  • 【PyCharm 安装与运用秘籍】Python 和 PyCharm 安装指引,看此篇保证学会(附带优质插件)。
  • 【秋招笔试题】多多排序
  • 基于GPU的Julia集应用程序
  • [产品管理-34]:什么是战略?什么是公司战略?什么是产品战略?什么是创新战略?什么是技术战略?什么是产品创新战略?
  • tauri开发软件中,使用tauri自带的api用浏览器打开指定的url链接
  • Spring Cloud 教程(一) | 认识Spring Cloud
  • iptables添加有线网卡与无线网卡桥接转发规则
  • Java语法-类和对象(上)
  • Ubuntu USB设备绑定
  • project generator 简单使用(二)之 CLion 与 AC6
  • top 使用技巧
  • 基于vue框架的刺梨销售管理系统pgl49(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 大势智慧亮相“第十届博博会”,展现数字文旅新质生产力!
  • React 中实现 vue keep-alive 功能的方法