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

[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--;
}

相关文章:

  • ddrnet 分割学习笔记
  • 深兰科技轮腿家用AI机器人荣获“2023年度城市更新科创大奖”
  • 【论文解读】GPT Understands, Too
  • Spring条件注解@Conditoinal+ Profile环境切换应用@Profile
  • --max-old-space-size=8192报错
  • [工业自动化-22]:西门子S7-15xxx编程 - 软件编程 - 如何PLC建立用户界面: SIMATIC 面板式HMI 或工控机PC HMI
  • JS-项目实战-更新水果单价更新小计更新总计
  • 快速构建高质量中文APP登录注册页面Figma源文件
  • Linux基本指令及周边(第一弹)
  • BeautifulReport测试报告框架
  • 计算机网络的性能指标
  • IDEA 2023搭建 SpringMVC +FreeMarker+JDBC
  • 【python】均值、中值和高斯滤波详解和示例
  • 以程序员的身份使用curl获取速卖通详情
  • 第四章 将对象映射到 XML - 异常
  • 2017 前端面试准备 - 收藏集 - 掘金
  • css选择器
  • echarts花样作死的坑
  • javascript从右向左截取指定位数字符的3种方法
  • Java精华积累:初学者都应该搞懂的问题
  • Less 日常用法
  • Otto开发初探——微服务依赖管理新利器
  • vue自定义指令实现v-tap插件
  • 从tcpdump抓包看TCP/IP协议
  • 新书推荐|Windows黑客编程技术详解
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • #WEB前端(HTML属性)
  • #每日一题合集#牛客JZ23-JZ33
  • (03)光刻——半导体电路的绘制
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)ssm码农论坛 毕业设计 231126
  • (九)One-Wire总线-DS18B20
  • (十三)Maven插件解析运行机制
  • (转)树状数组
  • (转)重识new
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .gitignore文件_Git:.gitignore
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET4.0并行计算技术基础(1)
  • .net操作Excel出错解决
  • [Angularjs]asp.net mvc+angularjs+web api单页应用
  • [bzoj4240] 有趣的家庭菜园
  • [C# 开发技巧]实现属于自己的截图工具
  • [I2C]I2C通信协议详解(二) --- I2C时序及规格指引
  • [IE编程] 打开/关闭IE8的光标浏览模式(Caret Browsing)
  • [JS]JavaScript 注释 输入输出语句
  • [Latex] Riemann 问题中的激波,接触间断,膨胀波的 Tikz 绘图
  • [ROS]安装tutlebot时无法下载解决方法
  • [SDOI2009]Elaxia的路线
  • [Servlet 3]会话管理、进阶API、监听过滤器