详解动态顺序表

news2024/11/25 15:53:09

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

👑💎💎👑💎💎👑 
💎💎💎自💎💎💎
💎💎💎信💎💎💎
👑💎💎 💎💎👑    希望在看完我的此篇博客后可以对你有帮助哟

👑👑💎💎💎👑👑   此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
👑👑👑💎👑👑👑     

目录 

一:顺序表的介绍

  1:顺序表定义

    顺序表是线性表的一种,首先顺序表是是用一段物理地址连续的存储单元依次存储数据元素的线性结构,多数情况下借助数组来存储

二:动态顺序表和静态顺序表区别

  1:静态顺序表:

   静态就体现了静态顺序表的特征,数组的空间大小是固定的

//静态顺序表的结构体的构造
#define N 10
typedef int SLDataTYpe;//便于实现各种数据类型,一改全改

typedef struct SeqList
{
	SLDataTYpe a[N];
	int size;//记录数据有效的个数
}SL;
 2:动态顺序表

 动态体现了是一个不断变化的过程,可以频繁进行扩容

//动态顺序表
typedef int SLDataType;//便于实现各种数据类型,一改全改
typedef struct SeqList
{
	SLDataType* a;
	int size;//记录数据有效的个数
	int capacity;//空间空间的容量
}SL;
3:二者区别

静态顺序表:以定长数组的形式存储

动态顺序表:以动态开辟的数组进行存储

本质上二者没有优劣之分,只不过动态顺序表多了一个成员:空间容量

三:动态顺序表的接口实现

1. 初始化

为了避免不必要的麻烦,我们在初始化的时候直接就对数组进行动态开辟

void SLInit(SL* psl)
{
	assert(psl);
	psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//先为数组开4 个空间
	if (psl->a == NULL)  //空间检查
	{
		printf("perror malloc\n");
		return;
	}
    // 开辟成功
	psl->size = 0;
	psl->capacity = 4;
}
2.销毁
void SLDestroy(SL* psl)
{
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	psl->capacity = 0;
	psl->size = 0;
}
3.尾插

分析:首先我们在尾插之前需要先进行空间容量检查

 

void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);
	//先判断空间是否足够
	CheckCapacity(psl);
	//之后直接尾插
	psl->a[psl->size] = x;
	psl->size++;
}
4.头插

分析:

1)空间容量的检查

2) 数据的挪动:从后往前挪动(避免数据覆盖)

3)下标边界值的确定

 

void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);
	//先判断空间是否足够
	CheckCapacity(psl);
	 挪动数据:从后往前挪动数据 注意边界的问题
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;

	
	 psl->size++;
}
 5.尾删

先进行判空,其次直接size--

void SLPopBack(SL* psl)
{
	assert(psl);
	//判断是否为空   温柔  / 暴力判断
	 if (psl->size == 0)
	{
		printf("为空 \n");
		return;
	}
	
	psl->size--;

}
6.头删

先进行判空

其次挪动数据:从前往后挪动

下标边界的确定

 

void SLPopFront(SL* psl)
{
	assert(psl);
	assert(psl->size);//判空
	// 挪动数据:从前往后挪数据
	int start = 0;
	while (start < psl->size - 1)
	{
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	//SLEarse(psl, 0);
	//注意:别忘了size--
	psl->size--;


}
7.任意位置的插入

1)空间容量检查

2)pos这个位置是否合法

3)数据挪动:和头插一样

 

void SLInsert(SL* psl, int pos, SLDataType x)
{
	assert(psl);
	// 先进行空间判断,以及位置的合法

	CheckCapacity(psl);
	
	assert(pos >= 0 && pos <= psl->size);  //这里可以取等,因为数组下标是连续的,可以在psl->size 这个位置插入
	
	int i = psl->size - 1;
	while (i >= pos)
	{
		psl->a[i + 1] = psl->a[i];
		i--;
	}
	psl->a[pos] = x;
	psl->size++;
	// 灵活运用: 头插,尾插就是此函数的一个特列

}
8.任意位置的删除

1)判空检查

2)pos是否合法

3)数据挪动:同头删一样

 

void SLEarse(SL* psl, int pos)
{
	assert(psl);
	//删除之前,先对pos这个位置判断是否合法,是否为空
	assert(pos >= 0 && pos < psl->size);  //注意这里没有必要取等  ,同时这个语句暗含着对判空的操作了
	int i = pos;
	//挪动数据:从前往后
	while (i < psl->size - 1)
	{
		psl->a[i] = psl->a[i + 1];
		i++;
	}
	//别忘了 size--

	psl->size--;

}

9.空间容量的检查

    当我们在进行头插,尾插,任意位置插入时都需要进行空间容量的检查,这里为了避免不必要的麻烦,写了一个函数

void CheckCapacity(SL* psl)
{
	assert(psl);
	if (psl->capacity == psl->size)
	{
		//realloc来扩容   void* realloc (void* ptr, size_t size);  第二个参数:扩容之后新的空间字节数,而不是要增加的字节数
		// 注意这样写是错误的,在free 的时候有问题  SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) *  4) * 2);//以原来2倍空间扩容
		SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) * psl->capacity) * 2);//以原来2倍空间扩容
		if (tmp == NULL)
		{
			printf("perror realloc\n");
			return;
		}
		// 扩容成功,进行更新
		psl->a = tmp;
		psl->capacity *= 2;

	}
}
10. 查找

1)前期的判断:位置是否合法?  顺序表是否为空表

2) 其实就是暴力求解,依次遍历顺序表即可,若是找到返回下标找不到返回-1

int  SLFind(SL* psl, SLDataType x)//查找
{
	assert(psl);
	assert(psl->size);//避免为空
	int i = 0;
	while (i < psl->size)
	{
		if (psl->a[i] == x)
		{
			return i;// 返回下标
		}
		i++;
	}
	return -1;//没有找到
}

11.任意位置修改 

1)依然是老生常谈,对位置以及顺序表进行判断

2)直接进行修改

void SLModify(SL* psl, int pos, SLDataType x) //指定位置修改
{
	assert(psl);
	assert(psl->size);//避免为空
	assert(pos >= 0 && pos <= psl->size - 1);
	psl->a[pos] = x;

}

完整代码:

SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

void SLInit(SL* psl)
{
	assert(psl);
	psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//先为数组开4 个空间
	if (psl->a == NULL)
	{
		printf("perror malloc\n");
		return;
	}
	psl->size = 0;
	psl->capacity = 4;
}
void SLDestroy(SL* psl)
{
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	psl->capacity = 0;
	psl->size = 0;
}
void CheckCapacity(SL* psl)
{
	assert(psl);
	if (psl->capacity == psl->size)
	{
		//realloc来扩容   void* realloc (void* ptr, size_t size);  第二个参数:扩容之后新的空间字节数,而不是要增加的字节数
		// 注意这样写是错误的,在free 的时候有问题  SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) *  4) * 2);//以原来2被空间扩容
		SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) * psl->capacity) * 2);//以原来2被空间扩容
		if (tmp == NULL)
		{
			printf("perror realloc\n");
			return;
		}
		// 扩容成功,进行更新
		psl->a = tmp;
		psl->capacity *= 2;

	}
}
void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);
	//先判断空间是否足够
	CheckCapacity(psl);
	//之后直接尾插
	/*psl->a[psl->size] = x;
	psl->size++;*/
	if (psl->size == 0)
	{
		psl->a[psl->size] = x;
		psl->size++;
	}
	else
	{
		SLInsert(psl, psl->size, x);
		//注意这里不用size++,因为SLInsert这个函数以及涉及到了
	}
}
void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);
	//先判断空间是否足够
	CheckCapacity(psl);
	 挪动数据:从后往前挪动数据 注意边界的问题
	//int end = psl->size - 1;
	//while (end >= 0)
	//{
	//	psl->a[end + 1] = psl->a[end];
	//	end--;
	//}
	//psl->a[0] = x;

	SLInsert(psl, 0, x);
	// psl->size++;
}
void SLPopBack(SL* psl)
{
	assert(psl);
	//判断是否为空   温柔  / 暴力判断
	 /*if (psl->size == 0)
	{
		printf("为空 \n");
		return;
	}*/
	assert(psl->size);
	psl->size--;

}
void SLPopFront(SL* psl)
{
	assert(psl);
	assert(psl->size);//判空
	// 挪动数据:从前往后挪数据
	int start = 0;
	while (start < psl->size - 1)
	{
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	//SLEarse(psl, 0);
	//注意:别忘了size--
	psl->size--;


}
void SLPrint(SL* psl)
{
	assert(psl);
	int i = 0;
	while (i < psl->size)
	{
		printf("%d ", psl->a[i]);
		i++;
	}
	printf("\n");
}
void SLEarse(SL* psl, int pos)
{
	assert(psl);
	//删除之前,先对pos这个位置判断是否合法,是否为空
	assert(pos >= 0 && pos < psl->size);  //注意这里没有必要取等  ,同时这个语句暗含着对判空的操作了
	int i = pos;
	//挪动数据:从前往后
	while (i < psl->size - 1)
	{
		psl->a[i] = psl->a[i + 1];
		i++;
	}
	//别忘了 size--

	psl->size--;

}
void SLInsert(SL* psl, int pos, SLDataType x)
{
	assert(psl);
	// 先进行空间判断,以及位置的合法

	CheckCapacity(psl);
	
	assert(pos >= 0 && pos <= psl->size);  //这里可以取等,因为数组下标是连续的,可以在psl->size 这个位置插入
	
	int i = psl->size - 1;
	while (i >= pos)
	{
		psl->a[i + 1] = psl->a[i];
		i--;
	}
	psl->a[pos] = x;
	psl->size++;
	// 灵活运用: 头插,尾插就是此函数的一个特列

}
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//顺序表分类:静态顺序表  动态顺序表
 
//静态的:空间开大了浪费,空间开小了不够用


/*静态顺序表的结构体的构造
#define N 10
typedef int SLDataTYpe;//便于实现各种数据类型,一改全改

typedef struct SeqList
{
	SLDataTYpe a[N];
	int size;//记录数据有效的个数
}SL;
*/

//动态顺序表
typedef int SLDataType;//便于实现各种数据类型,一改全改
typedef struct SeqList
{
	SLDataType* a;
	int size;//记录数据有效的个数
	int capacity;//空间空间的容量
}SL;
//接口函数的实现

void SLInit(SL* psl);
void SLDestroy(SL* psl);
void SLPushBack(SL* psl, SLDataType x);
void SLPushFront(SL* psl, SLDataType x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);
void SLPrint(SL* psl);
void SLEarse(SL* psl,int pos);
void SLInsert(SL* psl, int pos, SLDataType x);

结束语:

以上就是我今日要为大家分享的,希望各位大佬随时指正,咱一波关注走起,看到必回

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

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

相关文章

SIC产业链简述

同第一代硅半导体产业链类似&#xff0c;SiC产业链也分为以下几个环节&#xff1a; 设备和材料环节&#xff0c;包括晶体生长炉、MOCVD、切割设备、碳粉/硅粉/SiC粉体、石墨件等耗材&#xff1b; SiC衬底合外延环节&#xff0c;包括导SiC晶体生长、衬底晶片、外延片等制造&am…

[嵌入式专栏](FOC - 单电阻,双电阻,三电阻采样原理)

文章目录 1 . 前言2 . 三电阻方案2.1 电路接法2.2 采样原理2.3 采样注意事项 3 . 双电阻方案3.1 电路接法3.2 采样原理3.3 采样注意事项 4 . 单电阻方案4.1 电路接法4.2 采样原理4.3 采样注意事项4.4 采样时机4.5 开关管状态-电流方向 5 . 运放接法6 . AD采样周期7 . 小结 【极…

Dryad数据库学习

从一篇science论文中看到数据存储在了这个平台&#xff0c;这里分享一下&#xff1a;datadryad.org 亲测无需注册&#xff0c;可以直接下载&#xff0c;从一个数据测试看&#xff0c;数据存储在亚马逊云&#xff0c;下载速度还可以&#xff0c;6M/s的样子。 Dryad 是一个开放的…

Kioptrix-5

环境搭建 将原来的网络适配器删除掉&#xff0c;重新配置一个即可&#xff01; 靶场下载地址&#xff1a;Kioptrix: 2014 (#5) ~ VulnHub 信息收集 nmap -sn 192.168.1.0/24 -oN live.port 发现存活主机为192.168.1.159&#xff0c;探测开放的端口信息&#xff1a; # nmap…

2024年最火爆的前端技术:虚拟DOM让页面性能飞升!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 前言 正文 &#x1f4d8; 一、什么是虚拟D…

KBDNO1.DLL文件缺失,软件或游戏无法启动运行,怎样快速修复

不少小伙伴&#xff0c;求助电脑报错“KBDNO1.DLL文件缺失&#xff0c;软件或游戏无法启动或运行”&#xff0c;应该怎么办&#xff1f; 首先&#xff0c;我们先来了解“KBDNO1.DLL文件”是什么&#xff1f; KBDNO1.DLL是Windows操作系统中的一个动态链接库文件&#xff0c;主…

Nginx解决跨域问题过程

学习Nginx解决跨域问题 结果 server {listen 22222;server_name localhost;location / {if ($request_method OPTIONS) {add_header Access-Control-Allow-Origin http://localhost:8080;add_header Access-Control-Allow-Headers *;add_header Access-Control-Allo…

Debezium日常分享系列之:Debezium 通知

Debezium日常分享系列之&#xff1a;Debezium 通知 一、概论二、Debezium通知格式三、Debezium 有关初始快照状态的通知四、Debezium 有关增量快照进度的通知五、启用 Debezium 通知六、访问 Debezium JMX 通知七、自定义通知渠道八、应用案例 一、概论 Debezium 通知提供了一…

Excel中部分sheet页隐藏并设置访问密码

1、新建sheet1 2、新建sheet2 3、隐藏sheet2 4、保护工作簿、输密码 5、密码二次确认 6、隐藏的sheet2已经查看不了 7、想要查看时&#xff0c;按图示输入原密码即可 8、查看sheet2内容

混合编程—C++程序中python脚本的嵌入方法(理论部分)

一、C与Python高级编程语言简概 &#xff08;一&#xff09;C C是一种被广泛使用的计算机程序设计语言。它是一种通用程序设计语言&#xff0c;支持多重编程范式&#xff0c;例如过程化程序设计&#xff08;Procedural programming&#xff09;、面向对象程序设计&#xff08;…

no和not的应用场景

语法 后面直接跟名词&#xff1a;no 后面不是跟名词&#xff1a;not 案例

java struts2教务管理系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目

一、源码特点 java struts2 教务管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助 struts2 框架开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库…

深度学习|2.11 向量化vectorization

2.11 向量化的作用 向量化可以使得向量中的每一个维度的数据进行并行计算&#xff0c;从而加快了神经网络的计算速度。 验证 其他

详解 MySql InnoDB 的 MVCC 实现机制

目录 一. 前言 二. 认识 MVCC 2.1. 什么是 MVCC&#xff1f; 2.2. 什么是当前读和快照读&#xff1f; 2.3. 当前读、快照读和 MVCC 的关系 2.4. MVCC 能解决什么问题&#xff0c;好处是什么&#xff1f; 2.5. 小结 三. MVCC 的实现原理 3.1. 隐式字段 3.2. undo 日志…

4-文献阅读-A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction

目录 文献阅读—A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction0、选这篇文章的原因1、文章的主要内容和贡献2、使用的数据集3、结果及分析4、郭郭有话说 文献阅读—A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction 0…

一元函数微分学——刷题(12

目录 1.题目&#xff1a;2.解题思路和步骤&#xff1a;3.总结&#xff1a;小结&#xff1a; 1.题目&#xff1a; 2.解题思路和步骤&#xff1a; 注意两个y的区别即可 都可以在图中画出来&#xff0c;所以就非常好比较 3.总结&#xff1a; 理解两种y的区别即可 小结&…

【C#】知识点实践序列之Lock简单解决并发引起数据重复问题

欢迎来到《小5讲堂之知识点实践序列》文章&#xff0c;大家好&#xff0c;我是全栈小5。 这是2023年第3篇文章&#xff0c;此篇文章是C#知识点实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 本篇在Lock锁定代码块基…

Kubernetes(k8s):Namespace详解

Kubernetes&#xff08;k8s&#xff09;&#xff1a;Namespace详解 一、Namespace简介1.1 什么是Namespace1.2 Namespace的作用1.3 命名空间的分类 二、创建和管理Namespace2.1 创建Namespace2.2 管理Namespace 三、Namespace的实战应用3.1 部署多个项目3.2 环境隔离3.3 资源配…

JMeter 简单使用

JMeter 简介 Apache JMeter 是一款流行的性能测试工具&#xff0c;可以用来模拟用户行为并对系统进行压力测试。 安装 官方网站&#xff1a;http://jmeter.apache.org/ 在window下解压后&#xff0c; 运行 “bin/jmeter.bat” Jmeter 支持中文&#xff0c; 启动 Jmeter 后&…

SpringCloud微服务 【实用篇】| Dockerfile自定义镜像、DockerCompose

目录 一&#xff1a;Dockerfile自定义镜像 1. 镜像结构 2. Dockerfile语法 3. 构建Java项目 二&#xff1a; Docker-Compose 1. 初识DockerCompose 2. 部署微服务集群 前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…