当前位置: 首页 > news >正文

数据结构与算法——顺序表的实现以及增、插、删、查、印、毁

文章目录

  • 一、前言
  • 二、顺序表的概念与结构
    • 2.1顺序表的概念
    • 2.2顺序表的结构
  • 三、顺序表的分类
    • 3.1静态顺序表
      • 3.1.1静态顺序表的弊端
    • 3.2动态顺序表
      • 3.2.1动态顺序表的相对利弊
      • 3.2.2动态顺序表的增容方式
  • 四、顺序表的增、插、删、查、印、毁
    • 4.1 顺序表的增容
    • 4.2顺序表的尾插和头插
      • 4.2.1尾插
      • 4.2.2头插
      • 4.2.3指定位置插入
    • 4.3顺序表的尾删和头删
      • 4.3.1尾删
      • 4.3.2头删
      • 4.3.3指定位置删除
    • 4.4顺序表的查找
    • 4.5顺序表的打印
    • 4.6顺序表的销毁
  • 五、整体代码分析
    • 5.1头文件——SeList.h
      • 5.1.1头文件的作用
      • 5.1.2头文件代码展示
    • 5.2主体代码文件——SeList.c
    • 5.3测试文件——test.c
      • 5.3.1测试文件的作用
      • 5.3.2测试文件具体演示
        • 5.3.2.1尾插演示
        • 5.3.2.2头插演示
        • 5.3.2.3尾删演示
        • 5.3.2.4头删演示
        • 5.3.2.5指定位置插入演示
        • 5.3.2.6指定位置删除演示
        • 5.3.2.7元素查找演示
        • 5.3.2.8空间销毁演示
      • 5.3.3测试文件代码展示
  • 六、总结

一、前言

Hello啊,各位老铁们,今天的你是否在继续学习呢?up呢最近也是在学习数据结构的时候被其魅力冲昏了头脑,也是沉淀了大概10天左右吧?这10天你们有没有想念up呢?其实有时候,我们也是需要做减法,一味的累计而不去消化,最后可能被撑死。所以大家在学完知识过后,也要去沉淀沉淀哦。好啦我们回归今天的的主题,up今天给大家分享的是数据结构——顺序表。

二、顺序表的概念与结构

2.1顺序表的概念

顺序表:用一段物理地址连续的储存单元依次存储数据元素的线性结构,它的本质是用数组存储

2.2顺序表的结构

在这里插入图片描述

三、顺序表的分类

顺序表可以分为静态顺序表动态顺序表两类。

3.1静态顺序表

在这里插入图片描述

3.1.1静态顺序表的弊端

静态顺序表相当于有一种“一锤定音”的效果,那肯定也有着非常明显的弊端:空间给少了不够用,给大了容易造成浪费

3.2动态顺序表

刚刚呢up介绍了静态顺序表,那么从逆向思维的角度来看,是不是也存在动态顺序表呢?答案是肯定的。
在这里插入图片描述

3.2.1动态顺序表的相对利弊

动态顺序表在一定程度上减少了空间的浪费,但是这只是相对的,也不排除造成空间浪费的可能。

3.2.2动态顺序表的增容方式

顾名思义,动态顺序表那么它的内存空间大小肯定是动态的,在空间不够的同时回自动增容——成倍数增容,一般情况下是2倍增容。

四、顺序表的增、插、删、查、印、毁

4.1 顺序表的增容

在我们创建顺序表的时候,为了方便之后的使用,我们肯定会判断空间是否为满的情况,如果空间满了,那我们则需要实现增容。
画图展示:
在这里插入图片描述
代码展示
在这里插入图片描述

4.2顺序表的尾插和头插

4.2.1尾插

画图展示:
在这里插入图片描述

代码展示:
在这里插入图片描述

4.2.2头插

画图展示
在这里插入图片描述

在这里插入图片描述
代码展示
在这里插入图片描述

4.2.3指定位置插入

画图展示
在这里插入图片描述
在这里插入图片描述
代码展示:
在这里插入图片描述

4.3顺序表的尾删和头删

4.3.1尾删

画图展示·
在这里插入图片描述
代码展示:
在这里插入图片描述

4.3.2头删

画图展示
在这里插入图片描述
代码展示:
在这里插入图片描述

4.3.3指定位置删除

画图展示:
在这里插入图片描述
代码展示:
在这里插入图片描述

4.4顺序表的查找

查找方法:从顺序表第一个元素开始依次遍历,判断每一个元素和要查找的元素是否相同,相同则返回
代码展示:
在这里插入图片描述

4.5顺序表的打印

打印方法:从顺序表第一个元素开始,依次遍历,打印每一个元素
代码展示:
在这里插入图片描述

4.6顺序表的销毁

代码展示:
在这里插入图片描述

五、整体代码分析

OK啊up刚刚已经给大家讲解完毕了顺序表的全部情况。但是有的兄弟就问:“up up,我还是觉得这样有点太生硬了,有整体分析一波的步骤吗?"作为一个非常宠粉的up,我只能说:有点,兄弟,有的。那我们现在就来整体分析一波。
我们顺序表的代码为了方便并且清晰地实现,实际上需要创建3个文件,一个头文件(SeList.h)和两个源文件(Selist.c 和 test.c)。这个时候又有宝子疑问了——明明可以只写一个源文件就解决了,为什么还要分为3个文件呢?不急,请往下看。

5.1头文件——SeList.h

5.1.1头文件的作用

我们之前在C语言的学习中,已经非常清晰地了解到了头文件的作用,具体由以下7点:
1、声明接口和模块化代码;
2、减少重复代码;
3、提高代码复用性;
4、加强类型安全检查;
5、防止重复包含;
6、支持库功能调用;
7、组织项目结构。

5.1.2头文件代码展示

在这里插入图片描述

//头文件SeList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
struct Sequelist
{
	SLDataType* arr;
	int size;
	int capacity;
};
typedef struct Sequelist SL;
void SLInit(SL* ps);// 初始化
void SLPrint(SL* ps);//打印
void SLDestroy(SL* ps);//销毁

void SLPushBack(SL* ps, SLDataType x);//尾插
void SLPushFront(SL* ps, SLDataType x);//头插
void SLPopBack(SL* ps);//尾删
void SLPopFront(SL* ps);//头删
void SLInsert(SL* ps, int pos, SLDataType x);//指定位置插入
void SLErase(SL* ps, int pos);//指定位置删除
int SLFind(SL* ps, SLDataType x);//查找

5.2主体代码文件——SeList.c

主体代码就是我们程序中用来实现功能的代码。我们将所有实现功能的代码放在一起,也更加的条理清晰。
请添加图片描述

//主体文件SeList.c
#include "SeList.h"
void SLInit(SL* ps)//初始化
{
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLCheckCapacity(SL* ps)//增容
{
	if (ps->size == ps->capacity)//空间已满
	{
		SLDataType newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//三目操作符判断原本空间是否为空,是则增容4个空间,不是则进行两倍增容
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL) //判断是否增容失败
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}
void SLPushBack(SL* ps, SLDataType x)//尾插
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;
}
void SLPushFront(SL* ps, SLDataType x)//头插
{
	assert(ps);//断言不为空
	SLCheckCapacity(ps);//判断是否需要增容
	for (int i = ps->size;i > 0;i--)//元素往后移动
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	++ps->size;
}
void SLPopBack(SL* ps)//尾删
{
	assert(ps && ps->size);
	--ps->size;
}
void SLPopFront(SL* ps)//头删
{
	assert(ps && ps->size);
	for (int i = 0;i< ps->size-1;i++)//从第二个元素开始依次往前移动
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}
void SLInsert(SL* ps, int pos, SLDataType x)//指定位置插入
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//前提条件判断
	SLCheckCapacity(ps);
	for (int i = ps->size;i > pos;i--)//从最后一个元素往后移,直到pos位置
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	++ps->size;
}
void SLErase(SL* ps, int pos)//指定位置删除
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//前提条件判断
	for (int i = pos;i < ps->size - 1;i++)//从pos位置后一个元素依次往前移动,直到最后一个元素
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}
int SLFind(SL* ps, SLDataType x)//查找元素
{
	for (int i = 0;i < ps->size;i++)//依次遍历
	{
		if (ps->arr[i] == x)
			return i;   //找到则返回i
	}
	return -1;          //找不到则返-1
}
void SLDestroy(SL* ps)//销毁
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLPrint(SL* ps)//打印
{
	for (int i = 0;i < ps->size;i++)//遍历打印
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

5.3测试文件——test.c

5.3.1测试文件的作用

最后就来到了我们的测试文件了,那么测试文件又有什么好处呢?
1、验证程序的正确性;
2、提高代码之路;
3、优化性能;
4、文档作用。

5.3.2测试文件具体演示

5.3.2.1尾插演示

在这里插入图片描述
在这里插入图片描述

5.3.2.2头插演示

在这里插入图片描述
在这里插入图片描述

5.3.2.3尾删演示

在这里插入图片描述
在这里插入图片描述

5.3.2.4头删演示

在这里插入图片描述

在这里插入图片描述

5.3.2.5指定位置插入演示

在这里插入图片描述
在这里插入图片描述

5.3.2.6指定位置删除演示

在这里插入图片描述
在这里插入图片描述

5.3.2.7元素查找演示

在这里插入图片描述
在这里插入图片描述

5.3.2.8空间销毁演示

在这里插入图片描述

5.3.3测试文件代码展示

//text.c
#include "SeList.h"
test01()
{
	SL s1;
	SLInit(&s1);
	//初始化
	//SLPushBack(&s1, 1);
	//SLPushBack(&s1, 2);
	//SLPushBack(&s1, 3);
	//SLPushBack(&s1, 4);
	//SLPrint(&s1);
	//尾插
	SLPushFront(&s1, 1);
	SLPushFront(&s1, 2);
	SLPushFront(&s1, 3);
	SLPushFront(&s1, 4);
	//SLPrint(&s1);
	//头插
	//SLPopBack(&s1);
	//SLPrint(&s1);
	//尾删
	//SLPopFront(&s1);
	//SLPrint(&s1);
	//SLInsert(&s1, 2, 5);//指定位置插入
	//SLPrint(&s1);
	//SLErase(&s1, 2);//指定位置删除
	//SLPrint(&s1);
	//int find = SLFind(&s1, 2);//元素查找
	//{
	//	if (find != -1)
	//		printf("找到了!\n");
	//	else
	//		printf("找不到!\n");
	//}
	//SLPrint(&s1);
	SLDestroy(&s1);
	//SLPrint(&s1);
}
int main()
{
	test01();
	return 0;
}

六、总结

以上就是关于数据结构——顺序表的全部知识。up在最后演示的部分可能注释的代码有一点多,也是麻烦各位宝子们在阅读的时候耐心一点。最后也希望各位宝子学有所获,精益求精。当然也希望大家可以一键三连,嘿嘿嘿。

时间的沉淀,会让努力变得更加珍贵。
在这里插入图片描述

相关文章:

  • MySQL-- 多表查询的分类,SQL92与SQL99,7种JOIN的实现,SQL99语法的新特性
  • Postman 全局 Header 如何设置?全局设置了解一下
  • 接口用例设计原则
  • 旋转变换原理
  • 养老更安心!智绅科技“智慧”养老系统,智在何处?
  • A SAM-guided Two-stream Lightweight Model for AnomalyDetection
  • springBoot统一响应类型3.3版本
  • 4、网工软考—VLAN配置—hybird配置
  • 以科技赋能,炫我云渲染受邀参加中关村文化科技融合影视精品创作研讨会!
  • 《白帽子讲 Web 安全》之跨站请求伪造
  • 剑指Offer44 -- 思维
  • Java Synchronized底层原理:Monitor机制、锁膨胀、自旋优化与偏向锁细节解密
  • vcpkg安装指定版本的库
  • 重磅推出稳联技术Profinet转CANopen网关智能工厂解决方案!
  • 磷酸铁锂电池自动分选机:新能源产业的智能新宠
  • 深入理解机器学习之TF-IDF:文本特征提取的核心技术
  • STM32 时钟树配置(debug)
  • Citus源码(1)分布式表行为测试
  • 自动化测试与 CAPTCHA 识别指南
  • notepad++ 正则表达式
  • 申伟强任上海申通地铁集团有限公司副总裁
  • 第1现场|俄媒称乌克兰网上出售北约对乌军培训手册
  • 海南保亭警方通报“两飞车党紧追女童”:两名初中生认错道歉
  • 中国旅游日|上天当个“显眼包”!体验低空经济的“飞”凡魅力
  • 浦江潮涌征帆劲,上海以高质量发展服务全国发展大局
  • 《掩耳盗邻》:富人劫富,是犯罪,也是赎罪?