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

article/2025/10/26 5:59:01

文章目录

  • 一、顺序表概念及结构
  • 二、动态顺序表和静态顺序表的选择
  • 三、动态顺序表的实现逻辑
    • (1)创建结构体
    • (2)具体函数实现
      • (*)顺序表初始化
      • (*)释放顺序表
      • (*)打印顺序表
      • (*)是否需要扩容
      • (*)顺序表尾插
      • (*) 顺序表头插
      • (*)顺序表尾插删除
      • (*)顺序表头插删除
      • (*)顺序表查找
      • (*)顺序表在pos位置插入x
      • (*)顺序表删除pos位置的值
  • 四、动态顺序表实现代码
    • (1)test.c
    • (2)SeqList.h
    • (3)SeqList.c
  • 五、动态顺序表测试结果

一、顺序表概念及结构

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

二、动态顺序表和静态顺序表的选择

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以我们实现动态顺序表。

三、动态顺序表的实现逻辑

(1)创建结构体

typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity; 
}SL;

使用动态顺序表先创建结构体是必须的,先使用typedef int SLDateType;是为了方便改类型,在结构体里创建三个成员变量,SLDateType* a,为了方便增容,用指针的形式,int size代表a指向空间里的个数,int capacity代表a指向空间里的容量。

(2)具体函数实现

(*)顺序表初始化

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

先用assert断言,为了更方便查看在哪个地方出错,初始化就是把ps指向的结构体成员变量a置为空指针,size和capacity置为0。

(*)释放顺序表

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

释放顺序表也就是把a指向的空间的释放掉,并把a置为空指针,而另外两个成员变量置为0。

(*)打印顺序表

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

打印顺序表只需要用for循环依次打印,用ps找到size,即成员个数,再用printf进行打印,ps找到数组a。

(*)是否需要扩容

void if_add(SL*ps)
{if (ps->capacity == ps->size){int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = (SLDateType*)realloc(ps->a, NewCapacity*sizeof(SLDateType));if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = NewCapacity;}
}

为了提高代码的可读性,把是否需要扩容封装一个函数,而且下面有好多函数需要用到。
先判断capacity和size是否相等,如果相等,说明需要增容,再用三目运算符判断capacity是否等于0,如是则设置一个有一定大小的初始值,反之,则指定的倍数进行扩容。再把它赋给Newcapacity,再realloc进行开辟空间,用另外一个指针tmp表示,再判断tmp是否为空,如是则用perror显示开辟失败,并非正常退出程序exit(-1),反之则把新指针再赋给原来的a,最后capacity进行更新,Newcapacity赋给capacity。

(*)顺序表尾插

void SeqListPushBack(SL* ps, SLDateType x)
{assert(ps);if_add(ps);ps->a[ps->size] = x;ps->size++;
}

尾插先判断空间是否足够,再把x依次插入ps->size元素下标的位置,并进行ps->size加加,记录已尾插的个数。

(*) 顺序表头插

void SeqListPushFront(SL* ps, SLDateType x)
{assert(ps);if_add(ps);for (int i = ps->size - 1; i >=0; i--){ps->a[i + 1] = ps->a[i];}ps->a[0] = x;ps->size++;
}

头插也是先判断空间是否足够,再从后面进行尾插,用for循环从i=ps->size开始,每头插一个就把此位置的值往后移,直到第一个位置也就是0位置可用的时候,在把x赋给0位置处,直到i<0为止,最后size加加。

(*)顺序表尾插删除

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

头删,需要用asser断言一下,里面的内容为ps->size>0,防止size<0,以便告诉我们在哪出错,最后直接ps->szie–

(*)顺序表头插删除

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

头插删除,直接用for循环把后面内容往前移,注意i是从1开始的,如果写成0会越界,而且也只能从1开始,因为删除的是开头的元素,最后ps->szie–。

(*)顺序表查找

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

顺序表查找返回值是int类型,返回的是下表元素,那就用for循环直接遍历,如果找到x,就返回下标元素i,最后遍历完也没有找到返回-1。
这个函数需要结合测试函数test.c的部分代码用,如下,如果返回不是-1,就打印下标元素i,否则打印失败。

int ret = SeqListFind(&sl, 6);if (ret!=-1){printf("%d\n", ret);}else{printf("find fail\n");}

(*)顺序表在pos位置插入x

void SeqListInsert(SL* ps, int pos, SLDateType x)
{assert(ps);assert(pos <= ps->size);if_add(ps);for (int i = ps->size-1; i >= pos; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}

顺序表在下标元素pos插入x,先写两个断言函数,pos不能比szie大,因为我们是在size个数里面插入,再判断是否需要扩容,再用for循环进行移动元素,初始位置为当前数组的最后一个元素开始,直到pos结束,也就是pos位置可用可插入的时候再进行插入x,最后size++。

(*)顺序表删除pos位置的值

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

顺序表删除下标pos位置的值,同上用assert进行断言,从
pos位置开始,进行覆盖,直到ps->size-1结束,防止越界,因为有可能capacity等于size,最后size–。

四、动态顺序表实现代码

(1)test.c

#include"SeqList.h"int main()
{SL sl;SeqListInit(&sl);SeqListPushBack(&sl, 1);SeqListPushBack(&sl, 2);SeqListPushBack(&sl, 3);SeqListPushBack(&sl, 4);SeqListPrint(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);SeqListPrint(&sl);SeqListPushFront(&sl,3);SeqListPushFront(&sl, 4);SeqListPushFront(&sl, 5);SeqListPrint(&sl);SeqListPopFront(&sl);SeqListPopFront(&sl);SeqListPrint(&sl);int ret = SeqListFind(&sl, 6);if (ret!=-1){printf("%d\n", ret);}else{printf("find fail\n");}SeqListInsert(&sl, 1, 4);SeqListPrint(&sl);SeqListInsert(&sl, 3, 6);SeqListPrint(&sl);SeqListErase(&sl, 2);SeqListPrint(&sl);SeqListDestroy(&sl);return 0;
}

(2)SeqList.h

#pragma once//防止头文件包含
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity; 
}SL;
void SeqListInit(SL* ps);//顺序表初始化
void SeqListDestroy(SL* ps);//释放顺序表void SeqListPrint(SL* ps);//打印顺序表
void SeqListPushBack(SL* ps, SLDateType x);//顺序表尾插
void SeqListPushFront(SL* ps, SLDateType x); //顺序表头插
void SeqListPopFront(SL* ps);//顺序表头插删除
void SeqListPopBack(SL* ps);//顺序表尾插删除
void if_add(SL* ps);//是否需要扩容int SeqListFind(SL* ps, SLDateType x);//顺序表查找
void SeqListInsert(SL* ps, int pos, SLDateType x); 顺序表在pos位置插入x
void SeqListErase(SL* ps, int pos);// 顺序表删除pos位置的值

(3)SeqList.c

#include"SeqList.h"
void SeqListInit(SL* ps)
{assert(ps);ps->a = NULL;ps->size = 0;ps->capacity = 0;}
void SeqListDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
void SeqListPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
void if_add(SL*ps)
{if (ps->capacity == ps->size){int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = (SLDateType*)realloc(ps->a, NewCapacity*sizeof(SLDateType));if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = NewCapacity;}
}
void SeqListPushBack(SL* ps, SLDateType x)
{assert(ps);if_add(ps);ps->a[ps->size] = x;ps->size++;
}
void SeqListPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;
}
void SeqListPushFront(SL* ps, SLDateType x)
{assert(ps);if_add(ps);for (int i = ps->size - 1; i >=0; i--){ps->a[i + 1] = ps->a[i];}ps->a[0] = x;ps->size++;
}
void SeqListPopFront(SL* ps)
{assert(ps);for (int i = 1; i < ps->size; i++){ps->a[i-1] = ps->a[i];}ps->size--;
}
int SeqListFind(SL* ps, SLDateType x)
{for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i;}}return -1;
}void SeqListInsert(SL* ps, int pos, SLDateType x)
{assert(ps);assert(pos <= ps->size);if_add(ps);for (int i = ps->size-1; i >= pos; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}
void SeqListErase(SL* ps, int pos)
{assert(ps && pos < ps->size);for (int i = pos; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

五、动态顺序表测试结果

在这里插入图片描述


http://chatgpt.dhexx.cn/article/sRR4vWSx.shtml

相关文章

mysql:详解创建表的常用数据类型

1.什么是数据类型 数据类型是指列、存储过程参数、表达式和局部变量的数据特征&#xff0c;它决定了数据的存储格式&#xff0c;代表了不同的信息类型。 有一些数据是要存储为数字的&#xff0c;数字当中有些是要存储为整数、小数、日期型等... 2.mysql常见数据类型 整数型浮…

群晖服务器创建文件夹,群晖Synology 创建共享文件夹视频图文教程

群晖 Synology 是 NAS网络存储服务器,虽然它的操作大部分都跟 Windows 差不多,但是还是有些许不同。今天我们就来学习学习如何创建群晖 Synology NAS网络存储服务器的共享文件夹。共享文件夹,可以理解为在 Windows 上的 C 、D、E盘或者是盘中的根目录。由于群晖 Synology NA…

【Windows10】Win10存储空间的作用以及如何创建存储空间

本文目录 一、不得不说的话 二、存储空间的作用 三、如何创建存储空间 四、特别提示 一、不得不说的话 默认情况下&#xff0c; Windows10 系统的控制面板中会有一个“储存空间”选项&#xff0c;不过大多用户都不知道这个选项有什么作用。接下来&#xff0c;就在本文中具…

win10下docker安装oracle及创建表空间

1、拉取oracle镜像 docker pull jaspeen/oracle-11g 2、查看镜像 docker images 3、下载oralce安装文件并解压 4、启动镜像 docker run --privileged --name oracle11g -p 1521:1521 -v D:\oracle:/install jaspeen/oracle-11g 5、等待安装完成显示如下&#xff1a; 6、更…

ejb模式_EJB的完整形式是什么?

ejb模式 EJB&#xff1a;企业Java Bean (EJB: Enterprise Java Bean) EJB is an abbreviation of Enterprise Java Bean. EJB is one of many Java application programming interfaces (API) for flexible and manageable structuring of Java Platform, Enterprise Edition (…

到底EJB是什么?

&#xfeff;&#xfeff; 到底EJB是什么&#xff1f;被口口相传的神神秘秘的&#xff0c;百度一番&#xff0c;总觉得没有讲清楚的&#xff0c;仍觉得一头雾水。百度了很久&#xff0c;也从网络的文章的只言片语中&#xff0c;渐渐有了头绪。 用通俗话说&#xff0c;EJB就是&a…

什么是EJB?不再神秘!

1. 我们不禁要问&#xff0c;什么是"服务集群"&#xff1f;什么是"企业级开发"&#xff1f; 既然说了EJB 是为了"服务集群"和"企业级开发"&#xff0c;那么&#xff0c;总得说说什么是所谓的"服务集群"和"企业级开发&…

jndi(是什么)和ejb容器的关系

如下: 转载了几篇关于ejb jndi的文章&#xff01; 转载: http://blog.csdn.net/zhaosg198312/article/details/3979435 JNDI避免了程序与数据库之间的紧耦合&#xff0c;使应用更加易于配置、易于部署。 JNDI的扩展&#xff1a; JNDI在满足了数据源配置的要求的基础上&#xff…

EJB是什么?

来源&#xff1a;http://blog.csdn.net/jojo52013145/article/details/5783677 1. 我们不禁要问&#xff0c;什么是"服务集群"&#xff1f;什么是"企业级开发"&#xff1f; 既然说了EJB 是为了"服务集群"和"企业级开发"&#xff0c;那…

EJB到底是什么

百科定义EJB&#xff1a; 被称为java企业bean&#xff0c;服务器端组件&#xff0c;核心应用是部署分布式应用程序。用它部署的系统不限定平台。实际上ejb是一种产品&#xff0c;描述了应用组件要解决的标准 标准&#xff1a; 可扩展 (Scalable)分布式 (Distributed)事务处理(T…

EJB是什么,以及weblogic和tomcat的区别

首先说一下weblogic和tomcat的区别 weblogic是 java应用服务器 用于开发、集成、部署和管理大型分布式web应用、网络应用和数据库应用 将java的动态功能和java enterprise标准的安全性引入大型网络应用的开发集成部署和管理之中。 weblogic中有domain &#xff0c;域是作为一…

到底EJB是什么

到底EJB是什么&#xff1f;被口口相传的神神秘秘的&#xff0c;百度一番&#xff0c;总觉得没有讲清楚的&#xff0c;仍觉得一头雾水。百度了很久&#xff0c;也从网络的文章的只言片语中&#xff0c;渐渐有了头绪。 用通俗话说&#xff0c;EJB就是&#xff1a;"把你编写的…

EJB是什么

1. 我们不禁要问&#xff0c;什么是"服务集群"&#xff1f;什么是"企业级开发"&#xff1f; 既然说了EJB 是为了"服务集群"和"企业级开发"&#xff0c;那么&#xff0c;总得说说什么是所谓的"服务 集群"和"企业级开发…

EJB到底是什么,真的那么神秘吗?

百科定义EJB&#xff1a; 被称为java企业bean&#xff0c;服务器端组件&#xff0c;核心应用是部署分布式应用程序。用它部署的系统不限定平台。实际上ejb是一种产品&#xff0c;描述了应用组件要解决的标准 标准&#xff1a; 可扩展 (Scalable)分布式 (Distributed)事务处理(T…

程序无法正常启动(0xc000007b) 解决的过程

版权声明&#xff1a;转载需标明该文链接。 https://blog.csdn.net/zaibeijixing/article/details/87785073 解决&#xff08;2019/2/20&#xff09; 之前基于opencv 的项目都完全没问题&#xff0c;现在新建的一个opencv程序出现上述错误。查阅网上资料&#xff0c;自己摸索&a…

“0xc000007b无法正常启动”我的解决方案

关于这个问题&#xff0c;网上有很多解决方案&#xff0c;但是你得找到自己的问题在哪。 有的说DirectX 9.0损坏&#xff0c;我试着恢复了一下&#xff0c;还是没有得到解决。 还是DLL的问题&#xff0c;可能是缺少或者32位和64位使用不合适。 我的问题最开始不是这个&#xf…

应用程序无法正常启动0xc000007b怎么解决

我们平时在使用电脑时&#xff0c;打开应用或者安装某些软件例如MySQL&#xff08;博主本人就是在安装MySQL时遇见的&#xff09;&#xff0c;有时候会出现提示“应用程序无法正常启动0xc000007b”&#xff0c;这个问题的原因是什么呢&#xff1f;博主本人去简单了解了一下&…

计算机无法启动应用程序怎么办,应用程序0xc000007b无法正常启动解决办法

最近经常有有用户在电脑系统上操作运行程序时就出错了&#xff0c;且遇到提示“应用程序无法正常启动(0xc000007b)”。这该怎么办呢&#xff1f;接下来&#xff0c;小编就向大家介绍应用程序无法正常启动提示错误0xc000007b的原因和解决方法。 出现“应用程序无法正常启动0xc00…

aapt 命令可应用于查看apk包名、主activity、版本等很多信息

aapt命令小结 互相学习&#xff0c;请关注我的微博&#xff1a;weibo.com/ganchaojiang aapt即Android Asset Packaging Tool.本文小结了一下该工具的用法。 1. aapt l[ist] [-v] [-a] file.{zip,jar,apk} List contents of Zip-compatible archive. 1.1 列出压缩文件目录…

Android:linux下aapt使用

Android&#xff1a;linux下aapt使用 aapt stands for Android Asset Packaging Tool and is included in the tools/ directory of the SDK. This tool allows you to view, create, and update Zip-compatible archives (zip, jar, apk). It can also compile resources into…