小菜坤日常上传gitee代码:https://gitee.com/qi-dunyan(所有的原码都放在了我上面的gitee仓库里)

数据结构知识点存放在专栏【数据结构】后续会持续更新
❤❤❤
个人简介:双一流非科班的一名小白,期待与各位大佬一起努力!
推荐数据结构书籍:《大话数据结构》

目录

  • 前言
  • 接口实现
    • 前期准备
    • 初始化
    • 尾插与尾删
    • 打印
    • 头插与头删
    • 查找
    • 在任意位置插入与删除
    • 销毁
    • 总结

前言

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

采用数组存储的原因是,数组的地址也是连续的,随着下标的增长而增长。其实在我们之前写的通讯录,本质其实就是一个顺序表。

顺序表又分为静态与动态顺序表,所谓静态顺序表,就是提前开好固定大小的数组空间,而动态顺序表与之相比则更加灵活多变,因此,我们大多使用的都是动态顺序表。


最后,数据结构这里一定要多画图,通过图形来写代,会很容易。

接口实现

前期准备

两个源文件。分别用来测试,以及存放函数定义 一个头文件。存放函数声明与头文件包含
(另建议:有些书本上面会写菜单栏,但是为了方便调试与观察,不建议书写菜单栏)

//动态顺序表
typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;//定义一个指针指向数组int size;//数据数量int capacity;//容量
}SeqList;

初始化

这里我们来实现初始化接口,我们可以在测试文件里直接定义一个结构体,也可以定义一个结构体指针,定义结构体的话就不用再malloc结构体空间了。

接口实现:
初始化

//初始化
void SeqListInit(SeqList* ps)
{//断言assert(ps);//初始化ps->a = NULL;//指针指向空(也可以在这里直接malloc出一个空间)ps->size = 0;ps->capacity = 0;
}

尾插与尾删

尾插

尾插的实现非常简单,就是直接在下标为size位置处进行插入即可。唯一需要注意的就是扩容情况,即size ==
capacity时就意味着空间已满,然后就得扩容,这里由于后面的一些插入也需要进行判断扩容,所以把它写成一个check函数,后面直接调用即可。

//检查扩容
void SeqListCheck(SeqList* ps)
{if (ps->capacity == ps->size){//容量为0时赋值4,每次扩容扩大2倍int Newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* pf = (SLDateType*)realloc(ps->a, Newcapacity * sizeof(SLDateType));if (pf == NULL){perror("realloc");return;}ps->a = pf;ps->capacity = Newcapacity;}
}

尾插

//尾插
void SeqListPushBack(SeqList* ps, SLDateType x)
{//断言assert(ps);//检查扩容SeqListCheck(ps);//插入数据ps->a[ps->size] = x;ps->size++;
}

尾删
我们发现,尾删也很简单,其实只需要size–,就可以实现尾删的功能了

但是这里需要注意的是,当顺序表为空的时候,是不能进行删除的!

//尾删
void SeqListPopBack(SeqList* ps)
{//断言assert(ps->size>0);ps->size--;
}

打印

这里我们写一个用来打印顺序表的函数,以便于我们用来打印观察,打印的实现也很简单,只需要打印下标从零开始,一直到 下标为size-1的即可

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

这里我们在测试文件里进行测试,看一下是否有问题:

//尾插尾删
void TestSeqList1()
{SeqList s;//定义结构体//初始化SeqListInit(&s);//尾插SeqListPushBack(&s,1);SeqListPushBack(&s, 2);SeqListPushBack(&s, 3);SeqListPushBack(&s, 4);SeqListPrint(&s); //1 2 3 4//尾删SeqListPopBack(&s);SeqListPopBack(&s);//打印SeqListPrint(&s);//1 2//一直删到为空SeqListPopBack(&s);SeqListPopBack(&s);SeqListPopBack(&s);SeqListPrint(&s);//error
}

我们发现,以上是没问题的,不管是增容、还是尾删到空继续尾删,都在我们掌控之中,接下来我们进行头插与头删的操作

头插与头删

头插
顾名思义就是在数组下标为0的位置进行插入,这里我们通过画图来理解,这里头插完后记得size++

头插的时候切记注意检查扩容情况!

//头插
void SeqListPushFront(SeqList*ps,SLDateType x)
{//断言assert(ps);//检查扩容SeqListCheck(ps);int end = ps->size-1;//挪动数据while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}//在头部插入数据ps->a[0] = x;ps->size++;
}

头删
所谓头删,就是删除头部数据,这里还是通过覆盖的方式,画图即可更加方便理解

切记空表状态不可进行删除!

//头删
void SeqListPopFront(SeqList* ps)
{assert(ps);assert(ps->size > 0);int begain = 0;//挪动while (begain < ps->size - 1){ps->a[begain] = ps->a[begain + 1];begain++;}ps->size--;
}

测试
这里通过测试发现,代码是没问题的

void TestSeqList2()
{SeqList s;SeqListInit(&s);//头插SeqListPushFront(&s, 6);SeqListPushFront(&s, 5);SeqListPushFront(&s, 4);SeqListPushFront(&s, 3);SeqListPrint(&s); // 3 4 5 6//头删SeqListPopFront(&s);SeqListPopFront(&s);SeqListPrint(&s);//5 6SeqListPopFront(&s);SeqListPopFront(&s);//删除空表SeqListPopFront(&s);SeqListPrint(&s);//error,报错
}

查找

顺序表查找也是一件很简单的事,从begain位置开始查找

//顺序表查找
int SeqListFind(SeqList* ps, SLDateType x,int begain)
{assert(ps);assert(begain>0&&begain<ps->size);//begain的位置必须在顺序表范围内(begain其实就是下标,从下标为begain位置处开始查找)int i = 0;//遍历数组进行查找for (i = begain; i < ps->size; i++){if (ps->a[i] == x){return i;//找到直接返回下标}}//查找不到,返回-1return -1;
}

查找本身并不复杂,就是遍历数组而已

在任意位置插入与删除

这里还是要通过画图,能更加容易理解,另外插入的时候一定注意扩容情况!

还有就是,这个pos必须是在数组的有效范围内,不能跑到别的地方插入数据,因为顺序表的地址是连续的,如果超过了这个范围,就不构成连续了,如下:

代码实现:

//在pos位置插入
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0);assert(pos <= ps->size);//检查扩容SeqListCheck(ps);int end = ps->size - 1; //挪动数据while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}

任意位置删除

另外,pos位置也必须在有效范围内

//pos位置删除
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0);assert(pos <= ps->size);int begain = pos + 1;//覆盖即可while (begain < ps->size){ps->a[begain - 1] = ps->a[begain];begain++;}ps->size--;
}

测试
在测试文件里通过数据来观察

//任意位置插入删除
void TestSeqList3()
{SeqList s;SeqListInit(&s);//初始化SeqListPushFront(&s, 6);SeqListPushFront(&s, 5);SeqListPushFront(&s, 4);SeqListPushFront(&s, 3);//pos位置插入SeqListInsert(&s, 2, 1);SeqListPrint(&s); // 3 4 1 5 6SeqListInsert(&s, 4, 1);SeqListPrint(&s); // 3 4 1 5 1 6//pos位置删除SeqListErase(&s, 4);SeqListErase(&s, 4);SeqListInsert(&s, 3, 4);SeqListPrint(&s); // 3 4 1 4 5
}

我们发现,也是没什么问题的,说明我们已经正式写完了整个顺序表。
不过这里有一点需要注意的是,任意位置的插入与删除,如果这个位置是下标为0的地方,这就等同于头插头删,如果这个pos是在下标为size处,这就是尾插尾删
所以我们的头插可以也写为:

//头插
void SeqListPushFront(SeqList*ps,SLDateType x)
{断言//assert(ps);检查扩容//SeqListCheck(ps);//int end = ps->size-1;挪动数据//while (end >= 0)//{//   ps->a[end + 1] = ps->a[end];//  end--;//}在头部插入数据//ps->a[0] = x;//ps->size++;SeqListInsert(ps, 0, x);//从0位置处插入,就是头插
}

其余类比也是同理。

销毁

最后是顺序表的销毁,也很简单,释放a指向的空间,并置空a指针,然后size与capacity归零即可
这里注意,假如a是个空指针(未开辟空间就直接释放),就不能进行释放,具体原因动态内存章节已讲解,即空指针不能释放,所以加了个if判断条件。

//释放
void SeqListDestroy(SeqList* ps)
{//断言assert(ps);//释放空间if (ps->a != NULL){free(ps->a);ps->a = NULL;ps->capacity = 0;ps->size = 0;}}

总结

最后再总结以下,需要注意的细节地方无非是传来的参数是否为空指针,涉及到任意位置就要考虑下pos是否位置合理,还有就是只要涉及插入数据的操作,就必然要考虑到扩容,涉及到删除的操作,就必然考虑到空表问题。
最后,一定要多画图,才能更好理解!顺序表本身并不难,包括后面的链表,多画图就会很好的理解!


end
生活原本沉闷,但跑起来就会有风!❤

【线性表】—动态顺序表的增删查改实现相关推荐

  1. 顺序表讲解和顺序表实现增删查改

    前言 顺序表是一种参见的数据结构 特点:类似数组的储存,需要预先开辟空间已备数据插入.(1)同时顺序表也因此会存在和数组同样的问题(例如:越界)(2)同时因为其类似与数组的结构给二分查找这种算法提供了 ...

  2. 【数据结构】顺序表(Seqlist)详解-增删查改

    一.顺序表 什么是顺序表: 顺序表表是用一段物理地址连续的存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改 要求数据是连续存入的 可动态增长的数据 属于线性表的一种 顺序表的 ...

  3. 【顺序表和链表】实现增删查改数据结构 OJ题编程

    目录 线性表 一.顺序表 1.使用顺序表MyArrayList增删查改 MyArrayList.java TestDemo.java 二.链表 1.带头 / 不带头 循环 / 非循环 2.创建链表并访 ...

  4. Mysql库及表的基本概念、增删查改操作以及表的约束、多表联查

    什么是数据库? 存储数据的仓库 数据库的存储介质:磁盘和内存. 为什么要用数据库不用文件?(数据库与文件进行数据存储的区别) 1.文件存储安全性低 2.数据库对数据进行良好的存储,查询以及管理 3.便 ...

  5. C语言实现顺序表(增删查改等数据管理)

    顺序表seqlist 小伙伴们,提到顺序表会想到什么呢? 数组?还是链表? 其实,数组和链表都是属于线性表,而链表在逻辑上是线性的,并非物理存储上也为线性:而数组无论在逻辑上还是物理存储上均为线性 所 ...

  6. 数据结构C语言实现顺序表——增删查改操作实现详解

    顺序表 顺序表是什么? 顺序表是将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示.实现增删查改的功能. 顺序表所需的头文件: #include<stdio.h> ...

  7. 数据结构之动态顺序表(含游戏菜单)

    上一篇文章我们谈了数据结构的静态顺序表,以及实现了静态顺序表,具体可以看我的上一篇文章->>>数据结构之静态顺序表. 我们可以知道,静态顺序表的缺点是:  因为使用的是定长数组,所以 ...

  8. 【数据结构】顺序表的增删查改 (C语言实现)

    文章目录 一.线性表 二.顺序表 1.什么是顺序表 2.顺序表的分类 三.动态顺序表的实现 1.结构的定义 2.顺序表的初始化 3.检查容量 4.在头部插入数据 5.在尾部插入数据 6.在指定位置插入 ...

  9. C++实现静态顺序表的增删查改以及初始化

    C++实现静态顺序表的增删查改 顺序表:用一段地址连续的存储单元依s次存储数据元素的线性结构,是线性表的一种. //SeqList.h#pragma once#include <assert.h ...

最新文章

  1. http路径转file会变成反斜杠_PHP session反序列化漏洞
  2. 数据结构一:链表(linux链表)
  3. 《构建高可用Linux服务器》卓越网和互动网上架了
  4. 正负样本不平衡处理方法总结
  5. [bzoj3489]A simple rmq problem_KD-Tree
  6. SQL Server应用程序中的高级SQL注入[转]
  7. 用matlab解根3乘根2,第六章 信号与系统v1.ppt
  8. Java初级程序员学习路线→中高级程序员
  9. mysql航空公司订票系统_航空订票系统(JAVA+SSH+MYSQL)
  10. 【采用】金融知识图谱技术与银行业应用研究
  11. ERROR: could not access file $libdir/postgis-2.3: No such file or director解决方法
  12. python地理位置聚类_python实现地理位置的聚类
  13. linux nic cpu 10%,cpu – NIC中的描述符概念
  14. 吕 思 伟 ---- 潘 爱 民 :: ATL 介 绍( 三) (转)
  15. 故障转移集群搭建高可用文件共享服务器
  16. 理论+股市数据实战,总结了五种常用聚类分析算法
  17. Android Widget——GridView 学习笔记
  18. Java基础:IO 流中的 flush
  19. Gensim官方教程翻译(二)——语料库与向量空间(Corpora and Vector Spaces)
  20. HashSet-哈希值

热门文章

  1. 用python 居然可以生成 情话、藏头诗、对联?
  2. CaNet-master装载图片数据和mask(index对应单张图片序号)
  3. NVIDIA DLSS2.0 AI渲染又一大飞跃
  4. Genesis漫谈区块链 | 什么是共识机制?
  5. sccm2007-2
  6. PHP开发的二级域名分发系统源码 已对接易支付
  7. SCSI、DeviceIoControl、SCSI_PASS_THROUGH、CDB
  8. 小米air13.3一代的win10系统重装
  9. 毕设springBoot+vue 在线音乐网站系统(含源码+论文)
  10. 我的世界服务器server.properties文本解析