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

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;//初始化容量大小为4ps->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.hqwc.cn/news/543561.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Test注解

学习2个变量&#xff1a;dataProvider和dataProviderClass 是什么&#xff1f;怎么用&#xff1f; dataProvider变量是什么&#xff1f; 看源码定义&#xff1a;此测试方法的数据提供程序的名称。 使用&#xff1a; 在Test注解中直接加程序名称 ProviderClass 数据提供者通…

揭示数据在内存中存储的秘密!

** ** 悟已往之不谏&#xff0c;知来者犹可追 ** ** 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 整数在内存中的存储 整数的表达方式有三种&#xff1a;原码、反码、补码。 三种表示方法均有符号位和数值位两部分…

[java基础揉碎]多态参数

多态参数 方法定义的形参类型为父类类型&#xff0c;实参类型允许为子类类型 例子: 定义一个员工类, 有名字和工资两个属性, 有年工资的方法 定义一个普通员工继承了员工类 , 重写了年工资的方法 定义一个经理类, 也继承了员工类, 同时经理多以了一个奖金的属性, 重写的年…

Linux高级IO_select、epoll

调用send/write、read/recv这些IO接口进行网络通信时&#xff0c;需要等待IO条件满足&#xff08;IO事件就绪&#xff09;才能正常拷贝数据。比如调用send/write需要等待TCP的发送缓冲区有剩余空间才能将数据拷贝到TCP发送缓冲区中&#xff0c;调用read/recv需要等待TCP的接收缓…

Java双非大二找实习记录

先说结论&#xff1a;2.22→3.6线上线下面了七家&#xff0c;最后oc两家小公司&#xff0c;接了其中一个。 本人bg&#xff1a; 真名不经传双非一本&#xff0c;无绩点无竞赛无奖项无实习&#xff0c;23年12月开始学java。若非要说一点相关的经历&#xff0c;就是有java基础&…

Python+Selenium- 环境搭建

一&#xff0c;Selenium 简介 Selenium是目前最流行的web自动化测试工具&#xff0c;也常用于网络爬虫&#xff0c;已经更新到3以上的版本。 1&#xff0c;组件 它提供了以下web自动化测试组件&#xff1a; Selenium IDE&#xff0c;Firefox浏览器的一个插件&#xff0c;提供…

CSS学习(2)-盒子模型

1. CSS 长度单位 px &#xff1a;像素。em &#xff1a;相对元素 font-size 的倍数。rem &#xff1a;相对根字体大小&#xff0c;html标签就是根。% &#xff1a;相对父元素计算。 注意&#xff1a; CSS 中设置长度&#xff0c;必须加单位&#xff0c;否则样式无效&#xff…

JavaScript入门-引入方式-基础语法

JavaScript-引入方式 引入方式1 <script >... ...</script> 在.html文件内部任何位置引入都可以 引入方式2 <script src"... ..."></script> 在.html文件外部创建js文件夹在文件夹里面创建.js文件 基础语法 书写语法 // 弹出警告窗 wind…

印度交易所股票行情数据API接口

1. 历史日线 # Restful API https://tsanghi.com/api/fin/stock/XNSE/daily?token{token}&ticker{ticker}默认返回全部历史数据&#xff0c;也可以使用参数start_date和end_date选择特定时间段。 更新时间&#xff1a;收盘后3~4小时。 更新周期&#xff1a;每天。 请求方式…

VMware虚拟机硬盘容量扩容方法

扩容后不会影响原文件。亲测有效&#xff0c;高效便捷 - 在关机状态下&#xff0c;先在VM上直接扩容硬盘容量&#xff0c;输入扩容后的硬盘最大容量 注意&#xff0c;如果想在原硬盘上增加容量&#xff0c;需要将原来的快照都删除 - 输入最大磁盘大小 运行虚拟机进入系统&…

docker搭建vulfocus靶场

靶场搭建的前提是具备docker容器的环境 环境准备&#xff1a; 在kali上安装docker 先是进行软件和源更新 sudo apt-get update开始安装 sudo apt-get install -y docker.io设置开机自启动 sudo systemctl enable docker --now查看状态 sudo systemctl status docker给当…

B端界面又丑又乱,也不会总结规范,来,我给5个规范模板,照着学

发5个别人总结的规范&#xff0c;一定会对你的B端系统改进&#xff0c;有帮助的。