[C/C++]数据结构----顺序表的实现(增删查改)

概念

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

一般顺序表可以分为两种结构: 

1.静态顺序表:采用定长数组存储元素

#define N 7
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType arr[N];  //定长数组
	int size;           //有效数据的个数
}SeqList;

 2.动态顺序表:使用动态开辟的数组存储

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;  //指向动态开辟的数组
	int size;		  //有效数据个数
	int capacity;	  //容量空间大小
}SeqList;

     由于静态顺序表只适用于确定知道需要多少数据的场景,如果静态顺序表的定长数组N定大了,就会造成空间浪费,如果N定小了, 空间又不够用.所以现实中通常都是使用动态顺序表,按需开辟空间.

接口及实现

typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;
	int size;
	int capacity;
}SeqList;
 
// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);
 
void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);
 
// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

1. 顺序表初始化

        在进行操作前,先断言一下传过来的指针是否为空,若为空则会在终端提示错误信息,要注意使用asssert(),需要包含头文件assert.h

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

   2.打印顺序表

        同样先检查指针是否为空,在遍历顺序表进行打印

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

3.顺序表的摧毁

        如果传过来的顺序表本身就是空指针,说明顺序表就不存在,不需要进行其他操作.若指针不为空,就把其定长数组指向空,把有效数据个数和容量赋值为0

void SeqListDestroy(SeqList* ps)
{
	assert(ps);
 
	if (ps->a != NULL)
	{
		free(ps->a);
		ps->a = NULL;
		ps->size = 0;
		ps->capacity = 0;
	}
}

4.顺序表尾插

        在进行插入操纵前,需要判断一下顺序表的有效数据个数是否大于等于已开辟的容量,如果小于的话,直接尾插即可,如果大于等于容量的话,就需要先进行扩容操作,再尾插,为了使代码更加简洁明了,可以把扩容操作单独封装成一个函数

void SeqListPushBack(SeqList* ps, SLDataType x)
{
	assert(ps);

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

扩容函数:

        如果size==capacity的话就要进行扩容,我们规定每次扩容二倍.由于我们在初始化顺序表时将容量定为0,如果是第一次扩容的话,我们需要先给其扩容一个固定的大小,以后的扩容直接在这个容量上扩大二倍即可.

void CheckCapacity(SeqList* ps)
{
	assert(ps);
	
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity*2;
		SLDataType* ret = (SLDataType*)realloc(ps->a, newcapacity* sizeof(SLDataType));
		if (ret == NULL)   //检查是否开辟成功
		{
			perror("realloc");    //如果不成功就打印开辟错误信息并返回
			return;
		}
		else
		{
			ps->a = ret;
			ps->capacity = newcapacity;   //更新容量大小
		}
	}
	
}

5.顺序表头插

因为要在数组头部插入数据,所以需要把头部腾出一个位置,这就需要将所有数据向后移动一个单位

void SeqListPushFront(SeqList* ps, SLDataType x)
{
	assert(ps);
 
 
	CheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}

6.顺序表头删

void SeqListPopFront(SeqList* ps) //头删
{
	assert(ps);
	for (int i = 1; i < ps->size; i++)
	{
		ps->a[i - 1] = ps->a[i];
	}
	ps->size--;
}

7.顺序表尾删

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

8.顺序表查找

int SeqListFind(SeqList* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	printf("未找到\n");
	return - 1;
}

9.顺序表在pos位置插入x

void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	for (int i = ps->size; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}

10.顺序表删除pos位置元素

void SeqListDelete(SeqList* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
 
 
	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}
 

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

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

相关文章

zookeeper学习记录

本文Java代码地址&#xff1a; https://gitee.com/blackjie_1/ljUp/tree/master/zookeeperDemo 个人博客网站&#xff1a;什么是快乐 基于docker 安装 拉取zookeeper 3.4.10 docker pull zookeeper:3.4.10启动服务端 docker run -d -p 2181:2181 -v /root/docker/zookeepe…

现在做跨境电商还需要全球代理IP吗?全球代理IP哪家靠谱?

随着全球互联网的发展&#xff0c;电商平台的发展和跨境贸易的便利化&#xff0c;跨境电商在过去几年中也一直呈现增长趋势&#xff0c;吸引了越来越多的企业和个体创业者入行。 然而&#xff0c;行业竞争也在不断加剧&#xff0c;跨境电商面临更多的越来越多的挑战&#xff0…

c语言中,/100和/100.0的区别是什么?

c语言中&#xff0c;/100和/100.0的区别是什么&#xff1f; 应该是整数除法和浮点数除法的区别吧。/100 时&#xff0c;结果只会保留整数部分&#xff0c;余数会丢弃。 最近很多小伙伴找我&#xff0c;说想要一些c语言的资料&#xff0c;然后我根据自己从业十年经验&#xff0…

哈夫曼编码详细证明步骤

关于哈夫曼编码&#xff0c;想必大家都很清楚&#xff0c;这里来讲解一下他的详细证明方法。代码的话就不给了网上一大堆&#xff0c;我再给也没什么意思&#xff0c;这里主要讲明白正确性的证明。我将采取两种方法进行证明&#xff0c;一种常规的方法&#xff0c;还有一种采取…

完整时间线!李开复Yi大模型套壳争议;第二届AI故事大赛;AI算命GPTs;LLM应用全栈开发笔记;GPT-5提上日程 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f440; 李开复「零一万物」大模型陷套壳争议&#xff0c;事件时间线完整梳理 https://huggingface.co/01-ai/Yi-34B/discussions/11#65531458…

振南技术干货集:比萨斜塔要倒了,倾斜传感器快来!(1)

注解目录 1、倾斜传感器的那些基础干货 1.1 典型应用场景 &#xff08;危楼、边坡、古建筑都是对倾斜敏感的。&#xff09; 1.2 倾斜传感器的原理 1.2.1 滚珠式倾斜开关 1.2.2 加速度式倾斜传感器 1)直接输出倾角 2)加速度计算倾角 3)倾角精度的提高 &#xff08;如果…

Kettle工具使用小结1

1.背景 客户数据库限定为tidb数据库&#xff0c;相关业务数据均存储在内。因为tidb数据库是分布式的&#xff0c;且不支持存储过程、job等功能&#xff0c;需要通过外部工具进行脚本批量处理&#xff0c;所以这里引入kettle进行脚本批量执行和作业调度。 2.环境信息 &#xf…

SpringBoot配置数据库密码加密的方法

由于系统安全的考虑,配置文件中不能出现明文密码的问题,本文就给大家详细介绍下springboot配置数据库密码加密的方法,下面话不多说了,来一起看看详细的介绍吧,需要的朋友可以参考下 1.导入依赖 <!--数据库密码加密--> <dependency><groupId>com.github.uli…

探索arkui(2)--- 布局(列表)--- 2(支持分组/实现响应滚动位置)

前端开发布局是指前端开发人员宣布他们开发的新网站或应用程序正式上线的活动。在前端开发布局中&#xff0c;开发人员通常会展示新网站或应用程序的设计、功能和用户体验&#xff0c;并向公众宣传新产品的特点和优势。前端开发布局通常是前端开发领域的重要事件&#xff0c;吸…

Leetcode88 合并两个有序数组

合并两个有序数组 题解1 正向(记得插1删1)题解2 逆向 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减…

WEB 自动化神器 TestCafe(一)—安装和入门篇

今天小编给大家带来WEB 自动化神器 TestCafe(一) —安装和入门篇 一、TestCafe 介绍&#xff1a; TestCafe 是一款基于 Node.js 的端到端 Web 自动化测试框架&#xff0c;支持 TypeScript 或 JavaScript 来编写测试用例&#xff0c;运行用例&#xff0c;并生成自动化测试报告。…

传输层——— UDP协议

文章目录 一.传输层1.再谈端口号2.端口号范围划分3.认识知名端口号4.两个问题5.netstat与iostat6.pidof 二.UDP协议1.UDP协议格式2.UDP协议的特点3.面向数据报4.UDP的缓冲区5.UDP使用注意事项6.基于UDP的应用层协议 一.传输层 在学习HTTP等应用层协议时&#xff0c;为了便于理…

计算机网络的发展

目录 一、计算机网络发展的四个阶段 1、第一阶段&#xff1a;面向终端的计算机网络&#xff08;20世纪50年代&#xff09; 2、第二阶段&#xff1a;计算机—计算机网络&#xff08;20世纪60年代&#xff09; 3、第三阶段&#xff1a;开放式标准化网络&#xff08;20世纪70年…

vue3别名配置(vite)

1、配置别名的优点&#xff1a; 在VUE项目中import导入文件时&#xff0c;可以写相对路径. 2、在vite.config.js中配置 a. 首先引入path import path from "path"/* */ b.在resolve添加别名&#xff0c;例如&#xff1a; alias:{"~":path.resolve(__di…

jQuery【jQuery树遍历、jQuery动画(一)、jQuery动画(二)】(四)-全面详解(学习总结---从入门到深化)

目录 jQuery树遍历 jQuery动画(一) jQuery动画(二) jQuery树遍历 1、 .children() 获得子元素&#xff0c;可以传递一个选择器参数 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-…

批量处理文件夹及子文件夹下文件名

从此烟雨落京城&#xff0c;一人撑伞两人行。 问题描述 下载的资源被打过标记&#xff0c;不能直接使用&#xff0c;甚是痛苦 问题&#xff1a; 所有文件的文件名都加入了【更多it教程 微信号&#xff1a;…】字段&#xff0c;包括当前文件夹和子文件夹的全部文件&#xff0c…

leetcode:链表的中间结点

1.题目描述 题目链接&#xff1a;876. 链表的中间结点 - 力扣&#xff08;LeetCode&#xff09; 我们先看题目描述&#xff1a; 2.解题思路 我们用画图用快慢指针来解决这个问题 定义一个快指针fast&#xff0c;一个慢指针slow 快指针一次走两个结点&#xff0c;慢指针一次…

vscode终端npm install报错

报错如下&#xff1a; npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion1, but package-lock.json was generated for lockfileVersion2. Ill try to do my best with it! npm ERR! code EPERM npm ERR! syscall open npm ERR! errno -4048…

【AI视野·今日Sound 声学论文速览 第三十四期】Thu, 26 Oct 2023

AI视野今日CS.Sound 声学论文速览 Thu, 26 Oct 2023 Totally 9 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Dynamic Processing Neural Network Architecture For Hearing Loss Compensation Authors Szymon Drgas, Lars Bramsl w, Archontis Poli…

LeetCode(21)反转字符串中的单词【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 151. 反转字符串中的单词 1.题目 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单…