顺序表和链表知识点

news2024/9/20 15:30:28

1 顺序表

顺序表是指用一段物理地址连续的空间去存储数据的线性结构。

顺序表有两种:静态顺序表,动态顺序表。

1.1 静态顺序表结构体定义

typedef int ElemDataSL;

typedef struct SequeList {
	ElemDataSL arr[100];
	int size;
}SL;

静态顺序表在创建结构体的时候就已经把容量固定,后期空间不够,不允许增加新空间,所以并不方便实际使用。

例子:通讯录(C语言实现)-CSDN博客

1.2 动态顺序表结构体定义

typedef int ElemDataSL;

typedef struct SequeList {
	ElemDataSL* arr;
	int size;
	int capatity;
}SL;

 动态顺序表在创建结构体的时候定义了arr的指针作为一段连续内存空间的首地址,如果有需要可以用realloc开辟新空间进行扩容处理。

1.2.1 接口声明

//初始化
void InitSequeList(SL* s);
//尾插
void SequeListPushBack(SL* s,ElemDataSL num);
//尾删
void SequeListPopBack(SL* s);
//头插
void SequeListPushFront(SL* s, ElemDataSL num);
//头删
void SequeListPopFront(SL* s);
//pos处插
void SequeListPushInsert(SL* s,ElemDataSL num,int pos);
//pos处删
void SequeListPopInsert(SL* s,int pos);
//显示
void SequeListShowData(SL* s);
// 顺序表删除pos位置的值
void SequeListErase(SL*s, size_t pos);
// 顺序表销毁
void SequeListDestory(SL* s);

1.2.2 初始化

//初始化
void InitSequeList(SL* s) {
	assert(s);
	s->arr = (ElemDataSL*)malloc(DefaultData * sizeof(ElemDataSL));
	s->capatity = DefaultData;
	s->size = 0;
}

1.2.3 尾插

//尾插
void SequeListPushBack(SL* s,ElemDataSL num) {
	assert(s);
	AddCapatity(s);
	s->arr[s->size] = num;
	s->size++;
}

 1.2.4 尾删

//尾删
void SequeListPopBack(SL* s)
{
    assert(s);
	s->size--;
}

1.2.5 头插

//头插
void SequeListPushFront(SL* s,ElemDataSL num) {
	AddCapatity(s);
	for (int i = s->size-1; i >=0; i--)
	{
		s->arr[i + 1] = s->arr[i];
	}
	s->arr[0] = num;
	s->size++;
}

1.2.6 头删

//头删
void SequeListPopFront(SL* s)
{
	for (int i = 0; i <= s->size - 1; i++)
	{
		s->arr[i] = s->arr[i + 1];
	}
	s->size--;
}

1.2.7 中间插入

//pos处插
void SequeListPushInsert(SL* s,ElemDataSL num,int pos)
{
	AddCapatity(s);
	for (int i = s->size - 1; i >= pos-1; i--)
	{
		s->arr[i + 1] = s->arr[i];
	}
	s->arr[pos-1] = num;
	s->size++;
}

1.2.8 中间删除

//pos处删
void SequeListPopInsert(SL* s, int pos) {
	for (int i = pos-1; i <= s->size - 1; i++)
	{
		s->arr[i] = s->arr[i + 1];
	}
	s->size--;
}

1.2.9 打印顺序表

//显示
void SequeListShowData(SL* s)
{
	assert(s);
	for (int i = 0; i < s->size; i++)
	{
		printf("%d ", s->arr[i]);
	}
	printf("\n");
}

1.3 顺序表销毁

// 顺序表销毁
void SequeListDestory(SL* s) {
	free(s->arr);
	s->arr = NULL;
}

顺序表优点:可以利用随机访问。

缺点:开辟空间可能会导致空间浪费,增删改查的时间复杂度为O(N)。

2 链表

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

注意:

1、链式结构在逻辑上是连续的,但在物理上非连续。

2、在堆上开辟空间。

3、在堆上申请空间,按照一定策略进行的,两次开辟的空间可能连续也可能不连续。

2.1 单链表

无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。

2.2 接口声明

typedef int SLDATATYPE;
typedef struct SListNode {
	int data;
	struct SListNode* next;
}SListNode;
//尾插
void SListPushBack(SListNode** pphead, SLDATATYPE num);
//尾删
void SListPopBack(SListNode* phead);
//头插
void SListPushFront(SListNode** pphead, SLDATATYPE num);
//头删
void SListPopFront(SListNode* phead);
//查找
SListNode* SListFind(SListNode* phead, SLDATATYPE num);
//中间后插
void SListInsertAfter(SListNode* pos, SLDATATYPE num);
//中间删
void SListEraseAfter(SListNode* pos);
//打印
void SListPrint(SListNode* phead);
//销毁链表
void SListDistory(SListNode** phead);

2.3 尾插

//尾插
void SListPushBack(SListNode* *pphead, SLDATATYPE num) {

	
	SListNode* NewNode = BuySListNode(num);
	if (*pphead == NULL)
	{
		*pphead= NewNode;
	}
	else
	{	SListNode* tail = *pphead;
		while (tail->next!=NULL)
		{
			tail = tail->next;
		}
		tail->next= NewNode;
	}
}

2.4 尾删

//尾删
void SListPopBack(SListNode** phead)
{
	SListNode* tail = *phead;
	SListNode* prev = tail;
	if (*phead == NULL)
	{
		return;
	}
	else if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}
		free(tail);
		prev->next = NULL;
	}
	

}

2.5 头插

//头插
void SListPushFront(SListNode** pphead, SLDATATYPE num)
{
	SListNode* newNode = BuySListNode(num);

	if ((*pphead) == NULL)
	{
		*pphead = newNode;
	}
	else
	{
		newNode->next = *pphead;
	}
	*pphead = newNode;
}

2.6 头删

//头删
void SListPopFront(SListNode* *pphead)
{	
	SListNode* head = *pphead;
	if (head == NULL)
	{
		return;
	}
	else if (head->next == NULL)
	{
		*pphead = NULL;
	}
	else
	{

		(*pphead) = (*pphead)->next;
		free(head);
	}
	
	
}

2.7 查找

SListNode* SListFind(SListNode* phead, SLDATATYPE num) {
	SListNode* ptr = phead;
	while (ptr)
	{
		if (ptr->data == num)
		{
			printf("%d找到了!\n",ptr->data);
			return  ptr;
		}
		ptr = ptr->next;
	}
	printf("%d没找到!\n",num);
	return NULL;
}

2.8 中间后插

void SListInsertAfter(SListNode* *pos, SLDATATYPE num)
{
	SListNode* newNode = BuySListNode(num);
	newNode->next = (*pos)->next;
	(*pos)->next = newNode;
}

2.9 中间后删

void SListEraseAfter(SListNode* pos)
{
	assert(pos);
	assert(pos->next);
	SListNode* next = pos->next;
	pos->next = next->next;
	free(next);
}

3 打印

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

3.1 销毁链表

void SListDistory(SListNode** phead)
{
	assert(*phead);
	SListNode* next = (*phead)->next;
	while (next)
	{
		free(*phead);
		*phead = next;
		next = next->next;
	}
	free(*phead);
	*phead = NULL;
}

单链表优点:需要增加多少个元素就开辟多少空间不会导致空间浪费,插入时间复杂度低。

缺点:不能随机访问,只能依次往后访问,无法实现从后往前。

2.2 双链表

头节点不存储有效数据。

2.2.1 接口声明

typedef int ListData;
typedef struct ListNode
{
	ListData data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;
//链表创建
ListNode* ListCreate();
//尾插
void ListPushBack(ListNode* phead, ListData x);
//尾删
void ListPopBack(ListNode* phead);
//头插
void ListPushFront(ListNode* phead, ListData x);
//头删
void ListPopFront(ListNode* phead);
//查找
ListNode* ListFind(ListNode* phead, ListData x);
//中间插
void ListInsert(ListNode* pos,ListData x);
//中间删
void ListErase(ListNode* pos);
//显示
void ListPrint(ListNode* phead);
//清空链表
void ListClear(ListNode** phead);
//销毁链表
void ListDestory(ListNode* phead);

2.2.2 创建新节点 


ListNode* BuyListNode(ListData x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	node->data = x;
	node->next = NULL;
	node->prev = NULL;
	return node;
}

2.2.3 双链表创建

ListNode* ListCreate() {
	ListNode* phead = BuyListNode(0);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

2.2.4 尾插 

//尾插
void ListPushBack(ListNode* phead, ListData x)
{
	assert(phead);
	ListNode* tail = phead->prev;
	ListNode* newNode = BuyListNode(x);
	tail->next = newNode;
	newNode->prev = tail;
	newNode->next = phead;
	phead->prev = newNode;
}

 2.2.5 尾删

//尾删
void ListPopBack(ListNode* phead)
{
	assert(phead->next != phead);
	/*ListNode* tail = phead->prev;
	ListNode* tailPrev = tail->prev;
	tailPrev->next = phead;
	phead->prev = tailPrev;*/
	ListErase(phead->prev);
}

2.2.6 头插

//头插
void ListPushFront(ListNode* phead, ListData x)
{
	ListNode* newNode = BuyListNode(x);
	ListNode* pheadNext = phead->next;
	phead->next = newNode;
	newNode->prev = phead;
	newNode->next = pheadNext;
	pheadNext->prev = newNode;
}

2.2.7 头删 

//头删
void ListPopFront(ListNode* phead)
{
	ListNode* pheadNext = phead->next;
	phead->next = pheadNext->next;
	pheadNext->next->prev = phead;
	free(pheadNext);
}

2.2.8 查找

//查找
ListNode* ListFind(ListNode* phead, ListData x)
{
	ListNode* pos = NULL;
	ListNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data == x)
		{
			pos = cur;
			break;
			
		}
		cur = cur->next;
	}
	return pos;
}

2.2.9 中间插

//中间插
void ListInsert(ListNode* pos, ListData x)
{
	assert(pos);
	/*ListNode* newNode = BuyListNode(x);
	ListNode* posPrev = pos->prev;
	newNode->next = pos;
	pos->prev = newNode;
	posPrev->next = newNode;
	newNode->prev = posPrev;*/
	ListPushFront(pos->prev, x);
}

2.3 中间删

//中间删
void ListErase(ListNode* pos)
{
	ListNode* posPrev = pos->prev;
	ListNode* posNext = pos->next;
	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
}

2.3.1 显示

//显示
void ListPrint(ListNode* phead)
{
	assert(phead);
	ListNode* tail = phead->next;
	
	while (tail != phead)
	{
		printf("%d ", tail->data);
		tail = tail->next;
	}
	
	printf("\n");
}

2.3.2 清空链表

void ListClear(ListNode** phead)
{
	ListNode* cur = (*phead)->next;
	while (cur != *phead)
	{
		ListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	(*phead)->next = *phead;
	(*phead)->prev = *phead;
}

2.3.3 销毁链表

//销毁链表
void ListDestory(ListNode** phead)
{
	ListClear(phead);
	free(*phead);
}

双链表优点:插入时间复杂度比单链表更低,可以前驱访问。

缺点:不能随机访问。

 3 顺序表和链表的区别

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2087118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++11的学习

1.初始化列表 在C98中&#xff0c;标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。 struct Fun {int x;int y; }; struct Date {Date(int _year, int _month, int _day):year( _year),month(_month),day(_day){}int year 2005;int month 01;int day …

【unity实战】Cinemachine虚拟相机+Character Controller实现俯视角、第三人称角色控制,复制粘贴即用

最终效果 文章目录 最终效果一、前言二、Character Controller参数介绍三、添加虚拟相机四、2.5D俯视角人物操作五、自带重力的SimpleMove 移动六、第三人称角色控制1、移动2、添加重力3、 加地面检测&#xff0c;限制在地面重力不要累加3.1、自定义球形区域检测3.2、使用isGro…

MMGPL: 基于图提示学习的多模态医学数据分析 文献速递-大模型与多模态诊断阿尔茨海默症与帕金森疾病应用

Title 题目 MMGPL: Multimodal Medical Data Analysis with Graph Prompt Learning MMGPL: 基于图提示学习的多模态医学数据分析 01 文献速递介绍 神经系统疾病&#xff0c;包括自闭症谱系障碍&#xff08;ASD&#xff09;&#xff08;Lord 等&#xff0c;2018&#xff09…

Socket【网络】

文章目录 源端口号和目的端口号端口号&&进程pid TCP协议和UDP协议网络字节序socket 接口sockaddrsocket代码 源端口号和目的端口号 端口号&#xff1a; 端口号是传输层协议的内容。端口号是一个2字节16位的整数。端口号用来标识一个进程&#xff0c;告诉操作系统&…

【SpringCloud应用框架】GateWay网关

Spring Cloud Alibaba 之初识GateWay网关 文章目录 一、网关介绍二、网关对比三、GateWay基本概念&#xff1a;执行流程&#xff1a; 总结 一、网关介绍 在微服务架构中&#xff0c;一个系统会被拆分为多个微服务。如果没有网关存在&#xff0c;我们只能在客户端记录梅哥为服务…

Windows下创建FTP服务器,实现文件共享

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 创建FTP服务器 在【启用和关闭 Windows 功能】中选中【FTP服务】【IIS管理控制台】 应用更改完成后&#xff0c;重启电脑。 执行 ipconfig 命令查看当前电脑…

LeetCode刷题:3.无重复字符的最长子串

问题&#xff1a;首先分析问题得出需求 1.要求得到一个唯一最长子串的序列的长度。 子串&#xff1a;依据其形式是拥有一段长度的&#xff0c;所以考虑滑动窗口 唯一&#xff1a;考虑使用HashSet 需求描述&#xff1a;要求得到滑动窗口的大小&#xff0c;也就是左右指针的距离&…

STC89C52 串口浅谈

文章目录 1. 串口1.1 串口概述1.2 串口相关概念1.3 UART1.4 STC89C52串口1.4.1 串口相关寄存器1.4.2 串口模式图 1.5 串口配置简单代码示例1.5.1 UART串口初始化1.5.2 串口中断函数模板 1. 串口 1.1 串口概述 串口&#xff08;serial&#xff09;是一种通讯接口&#xff0c;可…

如何在Mac电脑上本地部署Stable Diffusion:详细教程(webUI)

Stable Diffusion是一款强大的AI生成图像模型&#xff0c;它可以基于文本描述生成高质量的图像。对于想要在本地运行此模型的用户来说&#xff0c;使用Mac电脑部署Stable Diffusion是一个非常吸引人的选择&#xff0c;特别是对于M1或M2芯片的用户。本文将详细介绍如何在Mac上本…

【图像去噪】论文精读:Spatial-Adaptive Network for Single Image Denoising(SADNet)

请先看【专栏介绍文章】&#xff1a;【图像去噪&#xff08;Image Denoising&#xff09;】关于【图像去噪】专栏的相关说明&#xff0c;包含适配人群、专栏简介、专栏亮点、阅读方法、定价理由、品质承诺、关于更新、去噪概述、文章目录、资料汇总、问题汇总&#xff08;更新中…

数据结构(邓俊辉)学习笔记】串 15——BM_GS算法:综合性能

1.BM之性能 接下来&#xff0c;针对已经综合了 bc 和 gs 两种策略的 BM 算法&#xff0c;标定它对应的复杂度&#xff0c;并将这种算法与此前的 KMP 以及蛮力算法在性能上做一个综合的对比分析。 首先是 BM 算法本身的性能。 在空间方面&#xff0c;除了模式串和文本串本身&a…

Qt:玩转QPainter序列十

前言 最后的一个解读QPainter源码的系列&#xff0c;剩下的源码全部都是内联函数&#xff0c;自己看看就好。 正文 渲染相关 void setRenderHint(RenderHint hint, bool on true); 功能: 启用或禁用特定的渲染提示。参数: hint&#xff1a;指定要设置的渲染提示&#xff0c;…

基于Leaflet Legend的图例数据筛选实践-以某市教培时空分布为例

目录 前言 一、关于Leaflet.Legend组件 1、Legend组件的主要参数 2、相关参数 二、Legend图例可视化控制 1、违规教培信息的管理 2、违规培训信息时空可视化及图例渲染控制 3、成果展示 三、总结 前言 在很多的地理时空分析系统中&#xff0c;我们经常会遇到一些需求。…

运维-3.分库分表

分库分表 1.介绍2.Mycat概述3.Mycat入门4.Mycat配置4.1 schema.xml4.1.1 schema标签4.1.2 dataNode标签4.1.3 dataHost标签 4.2 rule.xml4.3 server.xml4.3.1 system标签4.3.2 user标签 5.Mycat分片5.1 垂直拆分5.2 水平拆分5.3 分片规则5.3.1 范围分片5.3.2 取模分片5.3.3 一致…

若依微服务Admin控制台不显示ruoyi-file问题解决

本地启动完若依微服务,发现Admin控制台只显示了6个服务,其中ruoyi-file启动成功,但是没有在Admin控制台中显示处理,本章问题,给出这个问题的解决办法。 一、什么是服务监控 监视当前系统应用状态、内存、线程、堆栈、日志等等相关信息,主要目的在服务出现问题或者快要出…

机器学习和深度学习·贝叶斯优化和optuna

贝叶斯优化 贝叶斯优化的思想 先验&#xff1a;取点 似然&#xff1a;假设分布 取了n个点之后… 后验&#xff1a;近似取得极值 贝叶斯优化的数学过程 在贝叶斯优化的数学过程当中&#xff0c;我们主要执行以下几个步骤&#xff1a; 1 定义需要估计的 f ( x ) f(x) f(x)以及…

零基础学习Python(七)

1. 字符串常用方法 lower()、upper()&#xff1a;转换为小写字符串、大写字符串 split(str)&#xff1a;按照指定字符串str进行分割&#xff0c;结果为列表&#xff1a; email "123qq.com" print(email.split("")) [123, qq.com] count(str)&#xf…

MySQL 系统库

文章目录 一. 概念二. performance_schema1. 概念 2. 检查当前数据库版本是否支持3. performance_schema表分类5. 配置与使用6. 查看执行失败的SQL语句7. 查看最近事务执行信息8. 小结 三. sys系统库1. 使用须知2. 使用3. 查看慢SQL语句慢在哪4. 小结 四. Information_schema1.…

中国城市经济韧性数据集(2007-2022年)

数据来源&#xff1a;数据来自历年《中国城市统计NJ》、各省市《统计NJ》及《中国区域经济统计NJ》 时间范围&#xff1a;2007-2022年 数据范围&#xff1a;中国地级市样例数据&#xff1a; 包含内容&#xff1a; 全部内容下载链接&#xff08;原始数据计算代码最终数据&…

Spring Boot DevTools:简化开发,实现热部署

Spring Boot DevTools&#xff1a;简化开发&#xff0c;实现热部署 1、如何集成&#xff1f;MavenGradle 2、主要特性3、注意事项 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Spring Boot DevTools是开发者的得力助手&#xff0c;它通过…