数据结构---顺序表

文章目录

  • 线性表
    • 线性表的定义
    • 线性表分类
  • 顺序表
    • 顺次表的存储结构
    • 实现顺序表的主要接口函数
    • 初始化顺序表
    • 顺序表尾插
    • 顺序表尾删
    • 顺序表头插
    • 顺序表头删
    • 在指定位置插入数据
    • 在指定的位置删除数据
    • 头插,头删,尾插,尾删新写法
    • 打印顺序表
    • 销毁顺序表

线性表

线性表的定义

  • 线性表是n个具有相同属性的数据元素的有限序列。
  • 线性表在逻辑上是线性结构,也就是说连续的一条直线。但是在物理结构上不一定是连续的
  • 线性表在物理结构(存储结构)上一般采用顺序和链式的形式存储

image.png

image.png

线性表分类

image.png

顺序表

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

  • 静态顺序表:使用定长的数组存储
  • 动态顺序表:使用动态开辟的数组存储

静态顺序表只适合确定需要存储多少数据的场景,如果存储数据量不确定的话,空间开太大浪费,开太小不够用。一般都会去使用动态顺序表,根据情况分配多大的空间。下面将介绍动态顺序表

顺次表的存储结构

图示
image.png

typedef int ElemType;
typedef struct SeqList
{
	ElemType* a;
	int size;
	int capacity;
}SeqList;

定义一个动态顺序表需要三个属性
1.存储空间的地址,需要一段空间来维护顺序表,需要知道顺序表的起始地址
2.顺序表的元素个数,记录顺序表的元素个数,
3.顺序表的空间容量,用来分配空间

实现顺序表的主要接口函数

//顺序表初始化
void SeqListInit(SeqList* ps);
//顺序表尾插
void SeqListPushBack(SeqList* ps, ElemType x);
//检查容量
void CheckCapicity(SeqList* ps);
//顺序表尾删
void SeqListPopBack(SeqList* ps);
//顺序表头插
void SeqListPushFront(SeqList* ps, ElemType x);
//顺序表头删
void SeqListPopFront(SeqList* ps);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, ElemType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
//打印顺序表
void SeqListprintf(SeqList* ps);
//销毁顺序表
void DestroyedSeqList(SeqList* ps);

初始化顺序表

这里先为顺序表申请了2个元素类型的空间大小。

void SeqListInit(SeqList* ps)
{
	ps->a = (ElemType*)malloc(sizeof(ElemType)*2);
	ps->size = 0;
	ps->capacity = 2;
}

顺序表尾插

在尾部插入的时候要考虑两种情况,分别是

image.png

  • 顺序表未满尾插:直接将元素放入尾部即可

image.png

  • 顺序表已满的情况下,则需要申请更大的空间来存放数据

image.png
代码实现:

void SeqListPushBack(SeqList* ps, ElemType x)
{
	assert(ps);
	//检查容量
	CheckCapicity(ps);
	//尾插
	ps->a[ps->size] = x;
	ps->size++;
}

这里将检查容量封装成一个函数,方便后面插入检查继续复用

void CheckCapicity(SeqList* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity * 2;
		ElemType* tmp = (ElemType*)realloc(ps->a,sizeof(ElemType)*newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

顺序表尾删

在尾删时,也应该考虑两种情况,分别是

image.png
-顺序表已空时,无需删除
-顺序表未空,直接删除尾部元素即可

image.png

代码实现:
这里提供两种写法,一种是暴力检查,程序直接崩溃,一种是防止越界程序可以正常运行

  • 暴力检查版
void SeqListPopBack(SeqList* ps)
{
	//判空
	assert(ps->size > 0);//如果尾删空顺序表,程序直接崩溃
	//删除
	--(ps->size);
}

image.png

  • 防止越界版
void SeqListPopBack(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//删除
	--(ps->size);
}

顺序表头插

和尾插一样,要考虑是否有空间,但是与尾插不同的地方在于,需要挪动数据进行插入
图解

image.png
代码实现

void SeqListPushFront(SeqList* ps, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[0] = x;
	++ps->size;
}

顺序表头删

头删和尾删一样,先判空。与尾删不一样的地方在于删完后需要挪动数据
图解

image.png
代码实现

void SeqListPopFront(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	int start = 0;
	while (start <= ps->size) 
	{
		ps->a[start] = ps->a[start + 1];
		start++;
	}
	--ps->size;
}

在指定位置插入数据

和头插的思想基本一样
图解

image.png
代码实现

void SeqListInsert(SeqList* ps, int pos, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[pos] = x;
	++ps->size;
}

在指定的位置删除数据

思想与头删基本一样
图解

image.png
代码实现

void SeqListErase(SeqList* ps, int pos)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	while (pos <= ps->size)
	{
		ps->a[pos] = ps->a[pos + 1];
		pos++;
	}
	--ps->size;
}

有了在指定位置插入和删除前提下,头插,头删,尾插,尾删新写法

头插,头删,尾插,尾删新写法

//头插
void SeqListPushFront(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, 0, x);
}
//头删
void SeqListPopFront(SeqList* ps)
{
	SeqListErase(ps, 0);
}
//尾插
void SeqListPushBack(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, ps->size,x);
}
//尾删
void SeqListPopBack(SeqList* ps)
{
	SeqListErase(ps, ps->size);
}

打印顺序表

void SeqListprintf(SeqList* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

销毁顺序表

动态开辟的内存需要我们主动去释放空间 这里需要主动free

void DestroyedSeqList(SeqList* ps)
{
	free(ps->a);
	ps->a == NULL;
	ps->capacity = ps->size = 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用yolov7进行多图像视频识别

1.yolov7你可以让你简单的部署,比起前几代来说特别简单 #下面是我转换老友记的测试视频,可以看到几乎可以准确预测 2.步骤 1.在github官网下载代码 https://github.com/WongKinYiu/yolov7 2.点击下载权重文件放到项目中 3.安装依赖,我的python版本是3.6的 pip install -r requ…

每日一练2023.11.27——考试座位号【PTA】

题目链接&#xff1a;L1-005 考试座位号 题目要求&#xff1a; 每个 PAT 考生在参加考试时都会被分配两个座位号&#xff0c;一个是试机座位&#xff0c;一个是考试座位。正常情况下&#xff0c;考生在入场时先得到试机座位号码&#xff0c;入座进入试机状态后&#xff0c;系…

Adobe Indesign操作

Indesign 界面 图像描摹 在Indesign中打开图片&#xff0c;选择图像描摹&#xff0c;鼠标点击。 然后&#xff0c;出现如下效果。 在此基础上&#xff0c;可以对图片进行进一步操作。 【心得】

【前端】多线程 worker

VUE3 引用 npm install worker-loader 在vue.config.js文件的defineConfig里加上配置参数 chainWebpack: config > {config.module.rule(worker-loader).test(/\.worker\.js$/).use({loader: worker-loader,options: {inline: true}}).loader(worker-loader).end()}先在…

循环单向链表(详解)

循环单向链表原理 循环单项链表项目结构 头文件RecycleLinlList.h 头文件具体代码 #ifndef RECYCLRLINKLIST #define RECYCLRLINKLIST#include <stdio.h> #include <stdlib.h>// 宏定义 #define CIRCLELINKLIST_TRUE 1 #define CIRCLELINKLIST_FALSE 0 // 链表…

ChatGPT 问世一周年之际,开源大模型能否迎头赶上?

就在11月30日&#xff0c;ChatGPT 迎来了它的问世一周年&#xff0c;这个来自 OpenAI 的强大AI在过去一年里取得了巨大的发展&#xff0c;迅速吸引各个领域的用户群体。 我们首先回忆一下 OpenAI和ChatGPT这一年的大事记&#xff08;表格由ChatGPT辅助生成&#xff09;&#x…

java基础面试题(二)

java后端面试题大全 3.JVM3.1 对象实例、类信息、常量、静态变量分别在运行时数据区的哪个位置?3.2 java类的加载流程3.3 ThreadLocal 3.JVM 3.1 对象实例、类信息、常量、静态变量分别在运行时数据区的哪个位置? 堆 对象实例、String常量池、基本类型常量池、静态变量方法…

设计模式详解(二):抽象工厂——Abstract Factory

目录导航 抽象工厂及其作用工厂方法的好处工厂方法的实现关系图实现步骤 工厂方法的适用场景工厂方法举例 抽象工厂及其作用 工厂方法是一种创建型设计模式。所谓创建型设计模式是说针对创建对象方面的设计模式。在面向对象的编程语言里&#xff0c;我们通过对象间的相互协作&…

ios-class-guard - iOS代码混淆与加固实践

​ 目录 ios-class-guard - iOS代码混淆与加固实践 摘要 引言 一、class-dump 二、ios-class-guard 混淆原理 三、ios-class-guard 混淆结果 四、ios-class-guar 的使用 ios-class-guard 不支持 Swift ios-class-guard 不支持 iPhoneOS SDK ios-class-guard --sdk-ro…

【紫光同创PCIE教程】——DMA读写/PIO内存读写TLP解析

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;http://www.meyesemi.com) 一&#xff1a;PIO内存读写操作TLP解析 PCIE有三种空间——内存空间、IO空间、配置空间&#xff0c;其中内存空…

设计一款可扩展和基于windows系统的一键处理表格小工具思路

原创/朱季谦 设计一款可扩展和基于windows系统的一键处理表格小工具思路 日常开发当中&#xff0c;业务人员经常会遇到一些重复性整理表格的事情&#xff0c;这时候&#xff0c;就可以通过一些方式进行自动化程序处理&#xff0c;提高工作&#xff08;摸鱼&#xff09;效率。 …

【机器视觉技术】:开创人工智能新时代

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1; 前言&#x1f324;️ 机器视觉技术的实现☁️ 图像采集☁️ 图像处理☁️ 数据建模☁️应用展示…

基于harbor管理helm charts的方法

前言 Helm是Kubernetes的包管理器。Helm使用一种称为charts的打包格式。自1.6.0版本以来&#xff0c;Harbor是一个复合的云原生注册表&#xff0c;支持容器镜像管理和Helm Chart管理。对Harbor中Helm charts的访问由基于角色的访问控制&#xff08;RBAC&#xff09;控制&#…

Servlet概念视频笔记

学习地址:121-尚硅谷-Servlet-什么是Servlet_哔哩哔哩_bilibili 目录 1.Servlet技术 a.什么是Servlet b.手动实现Servlet程序 c.url地址如何定位到Servlet程序去访问 d.Servlet的生命周期 e.GET 和 POST 请求的分发处理 f.通过继承 HttpServlet 实现 Servlet程序 g.使用…

分享82个清新唯美PPT,总有一款适合您

分享82个清新唯美PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;https://pan.baidu.com/s/1tnRpOR8Gexg9gjWz4z15Xw?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识付…

AI一键生成文案-免费AI一键生成文案的软件有哪些

AI一键生成文案的原理涉及自然语言处理&#xff08;NLP&#xff09;和机器学习技术。这种技术的核心是基于大量文本数据的模式识别和生成&#xff0c;通常使用深度学习模型&#xff0c;如循环神经网络&#xff08;RNN&#xff09;、长短期记忆网络&#xff08;LSTM&#xff09;…

今日公众号爆文排行

​写爆文公众号需要综合考虑多个因素&#xff0c;包括内容质量、受众需求、话题热度、推广策略等。在创作过程中&#xff0c;可以着重参考其他作品&#xff0c;学习其优点和技巧&#xff0c;但同时也要注意避免抄袭和侵权行为。以下是一些写爆文公众号的方法和建议&#xff1a;…

2023年第十二届数学建模国际赛小美赛D题望远镜的微光系数求解分析

2023年第十二届数学建模国际赛小美赛 D题 望远镜的微光系数 原题再现&#xff1a; 当我们使用普通光学望远镜在昏暗的光线下观察远处的目标时&#xff0c;入射孔径越大&#xff0c;进入双筒望远镜的光线就越多。望远镜的放大倍数越大&#xff0c;视野越窄&#xff0c;图像显示…

使用NVM管理多个版本的node.js

1、nvm介绍&#xff1a; nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nvm是node.js版本管理工具&#xff0c;为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js 2、下载nvm地址&#xff1a; https://d…

蓝桥杯day03——二进制间距

1.题目 给定一个正整数 n&#xff0c;找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1&#xff0c;返回 0 。 如果只有 0 将两个 1 分隔开&#xff08;可能不存在 0 &#xff09;&#xff0c;则认为这两个 1 彼此 相邻 。两个 1 之间的距离…