数据结构入门-顺序表链表

news/2024/11/29 8:55:05/

线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种实际中广泛使用多个数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以链式结构的形式存储。

顺序表

概念及结构

顺序表是一段物理地址连续的存储单元一次存储元素的线性结构,一般情况下采用数据存储。在数组上完成数据的增删查改。

顺序表一般可分为:

  • 静态顺序表:使用定长数组存储元素。
//顺序表的静态存储
#define N 7
typedef int SLDataType;   //整形数据typedef struct SeqList
{SLDataType array[N];  //定长数组,N=7事先定义。size_t size;          //有效数据的个数
}SeqList;
  • 动态顺序表:使用动态开辟的数组存储。
//顺序表的动态存储
typedef struct SeqList
{SLDataType* array; //指向动态开辟的数组size_t size;       //有效数据个数size_ capicity;    //容量空间的大小
}SeqList;

接口实现

静态顺序表只适用于确定和知道需要存储多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用,所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{SLDataType* array; // 指向动态开辟的数组size_t size ; // 有效数据个数size_t capicity ; // 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl, size_t capacity);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x); 
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

函数补全请关注我的博客更新~

链表

链表的概念及结构

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

  • 从上图可以看出,链式结构在逻辑上是连续的,但是在物理上不一定连续;
  • 现实中的节点一般都是从堆上申请出来的;
  • 从堆上申请的空间,是按照一定的策略分出来的,两次申请的空间可能连续也可能不连续。

链表的分类

实际中链表的结构非常多样,一下情况组合起来就有八种链表结构:

  • 单向或双向

  • 带头或者不带头

 

  • 循环或者非循环

 虽然有这么多种结构,但是最常用的只有两种

  • 无头单向非循环链表
  • 带头双向循环链表
1.无头单向非循环链表: 结构简单 ,一般不会单独用来存数据。实际中更多是作为 其他数据结构的子结 ,如哈希桶、图的邻接表等等。另外这种结构在 笔试面试 中出现很多。
2. 带头双向循环链表: 结构最复杂 ,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

链表的实现

// 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);
// 2、带头+双向+循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{LTDataType _data;struct ListNode* next;struct ListNode* prev;
}ListNode;
// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表销毁
void ListDestory(ListNode* plist);
// 双向链表打印
void ListPrint(ListNode* plist);
// 双向链表尾插
void ListPushBack(ListNode* plist, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* plist);
// 双向链表头插
void ListPushFront(ListNode* plist, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* plist);
// 双向链表查找
ListNode* ListFind(ListNode* plist, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);

顺序表和链表的区别和联系

不同点顺序表链表
存储空间上物理上一定连续逻辑上连续,物理上不一定
随机访问支持O(1)不支持O(n)
任意位置任意插入或者删除可能需要搬移元素,效率低O(n)只需要修改指针指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素高效存储+频繁访问任意位置插入删除频繁
缓存利用率


http://www.ppmy.cn/news/64859.html

相关文章

学习Maven Web 应用

Maven Web 应用 本章节我们将学习如何使用版本控制系统 Maven 来管理一个基于 web 的项目,如何创建、构建、部署已经运行一个 web 应用。 创建 Web 应用 我们可以使用 maven-archetype-webapp 插件来创建一个简单的 Java web 应用。 打开命令控制台,…

p72 内网安全-域横向 CSMSF 联动及应急响应初识

数据来源 演示案例 MSF&CobaltStrike 联动 ShellWEB 攻击应急响应朔源-后门,日志WIN 系统攻击应急响应朔源-后门,日志,流量临时给大家看看学的好的怎么干对应 CTF 比赛 案例1 - MSF&CobaltStrike联动Shell CS下载与安装:cobaltstrike的安装与基础使用_co…

Java代码重构学习笔记-简化条件表达式

Decompose Conditional (分解条件表达式) 它的主要目的是将复杂的条件语句分解为多个简单的条件语句,从而提高代码的可读性和可维护性。 举个例子,假设有一个计费系统,其中包含一个 calculateFee 方法,负责根据用户的账单信息计…

影像已成为小米手机向上的强劲动力

4月18日,小米正式发布13 Ultra。 这款新机一亮相,就以全球亮度最高的屏幕、以及出类拔萃的徕卡Summicron镜头征服了用户。 一、火爆的小米13 Ultra 这次发布会上,小米13 Ultra是与小米电视大师 86" Mini LED、小米平板6、小米手环8、…

ResearchRabbit.ai: 学术论文摘要研究工具

【产品介绍】 ResearchRabbit是一个帮助研究人员发现、跟踪和分享学术论文的平台。可以根据你的兴趣和收藏提供个性化的推荐和摘要,并且可以让你可视化论文和作者之间的网络关系。 Researchrabbit.ai是一个基于人工智能的文献搜索和管理工具,它可以帮助你…

qemu-基础篇——程序编译过程(四)

文章目录 程序编译过程声明GCC 常用工具链GCCBinutilsC 运行库 ENV编译过程预处理编译汇编链接 分析 ELF 文件ELF 文件的段反汇编 ELF 程序编译过程 计算机程序设计语言通常分为机器语言、汇编语言和高级语言三类。高级语言需要通过翻译成机器语言才能执行,而翻译的…

Dtop环球嘉年华全球Web3.0分布式私域电商生态发展峰会圆满举办

5月7日,Dtop环球嘉年华全球Web3.0分布式跨境私域电商生态发展峰会暨战略合作备忘录签署仪式在马来西亚首都吉隆坡隆重举办。此次峰会汇集了Dtop环球嘉年华韩国、新加坡、澳洲、泰国、印尼等国家的社区联合发起人,环球自治商学院地区代表及来自Dtop环球嘉年华不同国家的粉丝用户…

JMeter压力测试案例(商品超卖并发问题)

什么要对接口压测呢? 压力测试可以用来验证软件系统的稳定性和可靠性,在压力下测试系统的性能和稳定性,发现并解决潜在的问题,确保系统在高负载情况下不会崩溃。压力测试可以用来评估软件系统的容量和性能,通过模拟高负载情况下…