数据结构:详解【顺序表】的实现

news2024/12/23 2:04:10

1. 顺序表的定义

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。动态顺序表与数组的本质区别是——根据需要动态的开辟空间大小。

2. 顺序表的功能

动态顺序表的功能一般有如下几个:

  • 初始化顺序表
  • 打印顺序表中的数据
  • 检查顺序表的容量
  • 顺序表头部插入数据
  • 顺序表尾部插入数据
  • 顺序表头部删除数据
  • 顺序表尾部删除数据
  • 顺序表任意位置插入数据
  • 顺序表任意位置删除数据
  • 顺序表中查找数据
  • 顺序表中修改指定位置数据
  • 顺序表的销毁

3.顺序表各功能的实现

3.1 创建顺序表

typedef int SQDateType;//对int进行重命名,可增加代码的普适性。

typedef struct SeqList
{
	SQDateType* a;
	size_t size; //有效数据
	size_t capacity;//容量的空间大小
}SL;//对这个结构体重命名为SL,书写方便

在这里插入图片描述

3.2 初始化顺序表
由于建立顺序表后并没有原始空间,所以我们自行动态开辟空间,又因为后续要进行扩容,所以我们必须初始化容量大小。

void SeqListInit(SL*ps)
{
	ps->a = (SQDateType*)malloc(sizeof(SQDateType) * 4);//初始化开辟4个int类型的空间
	//检查是否开辟成功
	if (ps->a == NULL)
	{
		printf("malloc fail!\n");
		return;
	}
	ps->capacity = 4;//初始化容量大小为4
	ps->size = 0;
}

3.3 打印顺序表中的数据
对顺序表进行增删查改等操作后,我们要把数据打印在控制台以便观察。

void SeqListPrint(SL* ps)
{
	//判断顺序表中是否有数据
	assert(ps->size > 0);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

3.4 检查顺序表的容量
对顺序表进行插入(增加)数据的操作时,我们必须先对顺序表进行容量的检查,若容量不够,则扩容。
并且扩容的幅度一般是原来容量的2倍。

void CheckSeqListCapacity(SL*ps)
{
	assert(ps);//断言
	//检查容量是否已满
	if (ps->capacity == ps->size)
	{
		//扩容
		SQDateType* tmp = (SQDateType*)realloc(ps->a, ps->capacity * 2 * sizeof(SQDateType*));
		if (tmp == NULL)
		{
			printf("realloc fail!\n");
			return;
		}
		else
		{
			ps->a = tmp;
			ps->capacity *= 2;//容量增大为原来的两倍
		}
	}
}

3.5 顺序表头部插入数据
头插,意思是在顺序表的最前面插入一个数据。我们需要把顺序表里的原数据(如果原来有数据的话)从后往前向后挪一个空间,再把要插入的数据放到第一个位置即可。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1b879d6df276406d8a11e8655d9e8cb0.png
代码实现如下:

void SeqListPushFront(SL* ps, SQDateType x)
{
     assert(ps);
	//检查是否要扩容
	CheckSeqListCapacity(ps);

	int end = ps->size;
	for (end = ps->size ; end >0; end--)
	{
		ps->a[end] = ps->a[end - 1];
	}
	ps->a[end] = x;
	ps->size++;//有效数据+1
}

3.6 顺序表尾部插入数据
尾插,意思是在顺序表的最后面插入一个数据。只需要找到该位置的下标(ps->size处)直接插入即可。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/11372c84deae44a7b1dc038142252cc9.png

代码实现如下:

void SeqListPushBack(SL* ps, SQDateType x)
{
     assert(ps);
     //检查是否要扩容
	CheckSeqListCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;//有效数据+1
}

3.7 顺序表头部删除数据
头删,意思是删除一个顺序表最前面的数据。只需把原数据从前往后开始向前覆盖一个空间即可。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/589b3cd1ddcc4189be625c3189619a32.png

代码实现如下:

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);//断言,当顺序表内有数据时才删除
	
	for (int start = 0; start < ps->size; start++)
	{
		ps->a[start] = ps->a[start + 1];
	}
	ps->size--;//有效数据-1
}

3.8 顺序表尾部删除数据
尾删,直接删除顺序表中最后一个数据即可。

void SeqListPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;//有效数据-1
}

3.9 顺序表任意位置插入数据
在顺序表的pos位置处插入一个数据,先要把pos处及其后面的原数据向后挪一个空间,再把数据放入pos处。
在这里插入图片描述
代码实现如下:

void SeqListInsert(SL* ps, int pos, SQDateType x)
{
	assert(ps && pos < ps->size);//pos<size时才满足
	CheckSeqListCapacity(ps);

	int end = ps->size ;
	for (end = ps->size ; end > pos; end--)
	{
		ps->a[end] = ps->a[end-1];
	}
	ps->a[pos] = x;//在pos的位置放入数据
	ps->size++;//有效数据+1
}

3.10 顺序表任意位置删除数据
在顺序表的pos位置处删除一个数据,只要把pos处后面的数据向前覆盖一个空间。
在这里插入图片描述
代码实现如下:

void SeqListEarse(SL* ps, int pos)
{
	assert(ps && pos < ps->size);//pos<size时才满足
	int start = pos;
	for (start = pos; start < ps->size; start++)
	{
		ps->a[start] = ps->a[start + 1];
	}
	ps->size--;//有效数据-1
}

3.11 顺序表中查找数据
把顺序表中的数据循环遍历,判断每个数据与查找数据是否相等,若相等,返回1,否则返回-1。

int  SeqListFind(SL* ps, SQDateType x)
{
	assert(ps && ps->size > 0);//表中有数据时才能查找
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return 1;
			break;
		}
	}
	return -1;
}

3.12 顺序表中修改指定位置数据
只要在顺序表中找到指定位置,把修改的值赋给它即可。

void SeqListModify(SL* ps, int pos, SQDateType x)
{
	assert(ps && pos < ps->size);//要修改的位置要小于数据个数
	ps->a[pos] = x;
}

3.13 顺序表的销毁
顺序表的空间的动态开辟的,最后需要free释放空间,避免造成空间泄漏。

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

4. 完整代码

SeqList.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SQDateType;

typedef struct SeqList
{
	SQDateType* a;
	size_t size; //有效数据
	size_t capacity;//容量的空间大小
}SL;

//初始化顺序表
void SeqListInit(SL* ps);

//头部插入数据
void SeqListPushFront(SL* ps, SQDateType x);

//尾部插入数据
void SeqListPushBack(SL* ps, SQDateType x);

//头部删除数据
void SeqListPopFront(SL* ps);

//尾部删除数据
void SeqListPopBack(SL* ps);

//任意位置插入数据
void SeqListInsert(SL* ps, int pos,SQDateType x);

//任意位置删除数据
void SeqListEarse(SL* ps, int pos);

//打印数据函数
void SeqListPrint(SL* ps);

//查找数据
int SeqListFind(SL* ps, SQDateType x);

//修改指定位置数据
void SeqListModify(SL* ps, int pos, SQDateType x);

//销毁顺序表
void SeqListDestory(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 

#include "SeqList.h"

void SeqListInit(SL*ps)
{
	ps->a = (SQDateType*)malloc(sizeof(SQDateType) * 4);//初始化开辟4个int类型的空间
	if (ps->a == NULL)
	{
		printf("malloc fail!\n");
		return;
	}
	ps->capacity = 4;
	ps->size = 0;
}

void CheckSeqListCapacity(SL*ps)
{
	assert(ps);
	//检查容量是否已满
	if (ps->capacity == ps->size)
	{
		//扩容
		SQDateType* tmp = (SQDateType*)realloc(ps->a, ps->capacity * 2 * sizeof(SQDateType*));
		if (tmp == NULL)
		{
			printf("realloc fail!\n");
			return;
		}
		else
		{
			ps->a = tmp;
			ps->capacity *= 2;
		}
	}
}


void SeqListPushFront(SL* ps, SQDateType x)
{
	assert(ps);
	CheckSeqListCapacity(ps);

	int end = ps->size;
	for (end = ps->size ; end >0; end--)
	{
		ps->a[end] = ps->a[end - 1];
	}
	ps->a[end] = x;
	ps->size++;
}

void SeqListPrint(SL* ps)
{
	//判断顺序表中是否有数据
	assert(ps->size > 0);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

void SeqListPushBack(SL* ps, SQDateType x)
{
	CheckSeqListCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);
	for (int start = 0; start < ps->size; start++)
	{
		ps->a[start] = ps->a[start + 1];
	}
	ps->size--;
}

void SeqListPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

void SeqListInsert(SL* ps, int pos, SQDateType x)
{
	assert(ps && pos < ps->size);
	CheckSeqListCapacity(ps);

	int end = ps->size ;
	for (end = ps->size ; end > pos; end--)
	{
		ps->a[end] = ps->a[end-1];
	}
	ps->a[pos] = x;
	ps->size++;
}

void SeqListEarse(SL* ps, int pos)
{
	assert(ps && pos < ps->size);
	int start = pos;
	for (start = pos; start < ps->size; start++)
	{
		ps->a[start] = ps->a[start + 1];
	}
	ps->size--;
}

int  SeqListFind(SL* ps, SQDateType x)
{
	assert(ps && ps->size > 0);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return 1;
			break;
		}
	}
	return -1;
}

void SeqListModify(SL* ps, int pos, SQDateType x)
{
	assert(ps && pos < ps->size);
	ps->a[pos] = x;
}

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

test.c

#define _CRT_SECURE_NO_WARNINGS 

#include "SeqList.h"

void SeqListTest()
{
	SL sl;
	
	//在这里调用各数据接口(函数)进行测试
}

int main()
{

	SeqListTest();

	return 0;
}

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

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

相关文章

【网络安全】【密码学】【北京航空航天大学】实验七、流密码【Python实现】

实验七、流密码 实验目的 1、 了解常用的流密码算法&#xff0c;并对其进行实现&#xff1b; 2、 了解常用的伪随机数生成算法&#xff0c;并对其进行实现&#xff1b; 原理简介 流密码&#xff08;Stream Cipher&#xff09;也称为序列密码&#xff0c;它是对称密码算法的…

亚马逊扣店租/注册店铺可以使用虚拟卡吗?

亚马逊扣店租/注册店铺可以使用虚拟卡吗&#xff1f; 可以 一、亚马逊店铺类型 亚马逊提供了不同类型的店铺&#xff0c;以满足不同卖家的需求。以下是最常见的两种店铺类型&#xff1a; 1、亚马逊个人卖家店铺&#xff1a; 这是适合个人卖家的选项&#xff0c;通常称为&qu…

【相关问题解答2】bert中文文本摘要代码:结果输出为一些重复的标点符号和数字

【相关问题解答2】bert中文文本摘要代码 写在最前面问题1&#xff1a;tokenizer.py中encode函数&#xff0c;不能使用lower操作关于提问问题描述1一些建议1问题更新2&#xff1a;结果输出为一些重复的标点符号和数字一些建议21. 数据检查和预处理2. 模型和训练配置3. 过拟合和欠…

Anzo Capital昂首资本基础知识分享:货币对有几组

基础知识大分享&#xff0c;今天Anzo Capital昂首资本分享&#xff1a;外汇市场中的货币对有几组&#xff0c;都是哪些货币对&#xff1f;首先&#xff0c;货币对分为三组: 第一组&#xff1a;主要货币对 包括七种金融工具&#xff0c;占外汇市场所有交易业务的70%以上。 美…

大数据疑难问题2024

问题一&#xff1a; 集群部署一主一备&#xff0c;初始化操作没有问题&#xff0c;有两个namenode,再次重启显示只有node01有namenode 原因&#xff1a;Journalde服务需要在启动启动hdfs和yarn前再次启动 再次启动步骤&#xff1a; 1.启动3台节点的zookeeper&#xff0c;在3…

Thymeleaf 基本使用

01、Thymeleaf 官网地址&#xff1a;Thymeleafhttps://www.thymeleaf.org/ 简介 Thymeleaf是一种服务器端Java模板引擎&#xff0c;用于将数据渲染为HTML、XML、JavaScript等格式&#xff0c;并在Web浏览器中呈现给用户。 具体来说&#xff0c;Thymeleaf充当着视图层的角色&…

代码随想录day19(1)二叉树:对称二叉树(leetcode101)

题目要求&#xff1a;判断一棵二叉树是否轴对称 思路&#xff1a;如果二叉树是对称二叉树&#xff0c;说明此二叉树是可以左右翻转的&#xff0c;所以判断的时候我们同时遍历两棵子树&#xff0c;比较两棵子树的内、外侧是否相等&#xff0c;比较的时候我们实际上比较的是左孩…

Leedcode刷题——5 DFS+回溯

注&#xff1a;以下代码均为c 1. 电话号码的字母组合 思路&#xff1a; 例如&#xff1a;”23“ //1. 我自己写的 vector<string> letterCombinations(string digits) {if(digits "")return {};vector<string> state {""};string s;vecto…

读取txt文件并统计每行最长的单词以及长度

读取txt文件并统计每行最长的单词以及长度 题目 在 D:\\documant.txt 文本中,文件中有若干行英文文本,每行英文文本中有若干个单词&#xff0c;每个单词不会跨行出现每行至多包含100个字符,要求编写一个程序,处理文件,分析各行中的单词,找到每行中的最长单词&#xff0c;分别…

cmd 输入pip 提示不是内部或外部命令,也不是可运行的程序 或批处理文件。

解决办法&#xff1a; 把pthon的安装路径加入到环境变量中&#xff0c;重新打开cmd运行即可 比如&#xff1a;C:\Users\huanhuan\AppData\Local\Programs\Python\Python311\Scripts

测试环境搭建整套大数据系统(十:测试环境minio单节点部署)

一&#xff1a;部署minio 创建安装目录。 mkdir -p /data/server/minio/{bin,data,config,log}bin&#xff1a;二进制文件目录data&#xff1a;数据存储目录config&#xff1a;配置文件目录log&#xff1a;日志文件路径下载二进制安装包到bin目录&#xff0c;或者提前下载好拷…

edm邮件是什么意思:与普通邮件有何不同?

edm邮件是什么意思&#xff1f;如何优化邮件内容以提高转化率&#xff1f; edm邮件因其独特的营销价值而备受关注。那么&#xff0c;edm邮件究竟是什么意思呢&#xff1f;它与普通邮件又有哪些不同呢&#xff1f;下面&#xff0c;AokSend就来为大家介绍一下。 edm邮件的概念与…

KMP算法——解决字符串匹配问题

一般来说在你没学过KMP算法前&#xff0c;你解决字符串匹配问题会采用BF算法——BF算法&#xff0c;即暴力(Brute Force)算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配&#xff0c;若相等&#xff0c;…

这三个长辈必备的手机模式,你给他们设置了吗?

您是否曾听家里长辈说过手机图标字体太小看起来很吃力&#xff1f;是否曾担心家里长辈在手机上误安装恶意软件&#xff1f;是否曾因为各种骚扰和推销电话而感到困扰&#xff1f;现在&#xff0c;这些问题不再是难题&#xff0c;因为有了华为手机的长辈关怀功能——一键开启放大…

运维打工人,兼职跑外卖的第二个周末

北京&#xff0c;晴&#xff0c;西南风1级。 前序 今天天气还行&#xff0c;赶紧起来&#xff0c;把衣服都洗洗&#xff0c;准备准备&#xff0c;去田老师吃饭早饭了。 一个甜饼、一个茶叶蛋、3元自助粥花费7.5。5个5挺吉利的。 跑外卖的意义 两个字减肥&#xff0c;记录刚入…

HCIP --- BGP 综合实验

目录 实验拓扑图&#xff1a; 实验要求&#xff1a; 实验步骤&#xff1a; 1.划分IP地址 R1的配置 R2的配置 R3的配置 R4的配置 R5的配置 R6的配置 R7的配置 R8的配置 2.检测查询IP地址 3.OSPF 建邻 4.查询OSPF 建邻是否成功 5.AS 2 内部BGP 建邻 a. AS 2 内部 IBG…

淘宝扭蛋机小程序:探索未知的惊喜之旅

你是否曾在商场里被那闪闪发光的扭蛋机吸引&#xff0c;却因为种种原因无法下手&#xff1f;现在&#xff0c;淘宝扭蛋机小程序带给你全新的扭蛋体验&#xff0c;让你随时随地都能感受到那份未知的惊喜。 淘宝扭蛋机小程序是一款集娱乐与购物于一体的全新应用。它汇聚了众多热…

(开源项目)OpenHarmony、社区共建Sample合入要求

1.新增Sample功能不能重复于当前已有Sample的功能&#xff1b; 2.新增Sample的工程推荐使用ArkTS语言编写&#xff1b; 3.新增Sample的工程推荐使用Stage模型编写&#xff1b; 4.新增Sample的工程中需要包含UI自动化用例&#xff08;ohosTest工程模块&#xff09;&#xff0…

Windows11安装NodeJS18并配置环境变量

从官网下载&#xff0c;或者从百度网盘下载 解压下载的zip包&#xff1a; 重命名为nodejs&#xff1a; 在nodejs中添加cache和global两个目录&#xff1a; 将nodejs和nodejs\global添加到环境变量&#xff1a; 打开终端&#xff0c;输入&#xff1a; node -v接着配置…

AI新工具(20240312) Midjourney官方发布角色一致性功能;免费且开源的简历制作工具;精确克隆语调、控制声音风格

1: Midjourney角色一致性功能 使人物画像在多方面高度一致成为可能。 Midjourney的角色一致性功能的使用方法如下&#xff1a; ⭐在你的输入指令后面加上 --cref URL&#xff0c;其中URL是你选择的角色图像的链接。 ⭐你可以通过 --cw 参数来调整参照的强度&#xff0c;范围…