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

文章目录

  • 线性表
    • 线性表的顺序实现
      • 结点结构
      • 结点初始化
      • 增配空间Inc
      • 打印顺序表show_list
      • 线性表长度length
      • 尾部插入push_back
      • 头部插入push_front
      • 尾部删除pop_back
      • 头部删除pop_front
      • 按位置插入insert_pos
      • 按值查找find
      • 按位置删除delete_pos
      • 按值删除delete_val
      • 排序sort(冒泡;升序)
      • 逆置resver
      • 清除表clear
      • 销毁表destroy
      • 合并表merge

线性表

在数据元素的非空有限集中,(1)存在唯一的一个被称做“第一个”的数据元素;(2)存在唯一的一个被称做“最后一个”的数据元素;(3)除第一个之外,集合中的每个数据元素均只有一个前驱;(4)除最后一个之外,集合中每个数据元素均只有一个后继

线性表的顺序实现

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。

结点结构

#define SEQLIST_INIT_SIZE 8typedef struct SeqList {ElemType *base; // 线性表首地址int capacity; // 开辟的内存空间int size; // 有效存储
} SeqList;

结点初始化

开辟出一段空间(给定空间大小)

void InitSeqList(SeqList *list) {list->base = (ElemType *) malloc(sizeof(ElemType) * SEQLIST_INIT_SIZE);//开辟空间assert(list->base != NULL);list->capacity = SEQLIST_INIT_SIZE;list->size = 0;
}

malloc动态内存分配函数,用于申请一块连续的指定大小的内存块区域以ElementType *类型返回分配的内存区域地址:格式:指针名=(指针类型*)malloc(sizeof(指针类型)*数据数量)

②如果表达式的结果为“假”,assert()会打印出断言失败的信息Assertion failed:...,并调用abort()函数终止程序的执行Process finished with exit code 3;如果表达式的结果为“真”,assert()就什么也不做,程序继续往后执行

增配空间Inc

1.重新开辟内存空间,并判断是否增配空间成功,失败则增配失败返回false

2.更新结点线性表首地址和开辟的内存空间

3.之后每次插入数据操作前,添加判断条件:分配给表内存是否足够。不够则进行增配空间,增配空间失败时,才是真正的内存不足

#define INC_SIZE 3bool Inc(SeqList *list) {//对已有的空间进行分配,原来表开辟内存8,进行重新分配,即开辟8+3内存ElemType *newbase = (ElemType *) realloc(list->base, sizeof(ElemType) * (list->capacity + INC_SIZE));if (newbase == NULL) {printf("增配空间失败,内存不足\n");return false;}list->base = newbase;list->capacity += INC_SIZE;return true;
}

realloc函数指向在堆区重新开辟的内存块的起始地址:realloc(先前开辟的内存块的指针--也就是malloc之前申请的那块内存空间,即需要调整大小的内存空间,新开辟的那块内存空间的字节数),返回值为调整之后的内存的起始地址

打印顺序表show_list

void show_list(SeqList *list) {for (int i = 0; i < list->size; i++) {printf("%d", list->base[i]);}printf("\n");
}

线性表长度length

int length(SeqList *list) {return list->size;
}

尾部插入push_back

插入6 7 9后顺序表中数据顺序为:6 7 9

1.判断有效存储是否小于开辟的内存空间,即判断开辟的空间是否已满,满了不能插入数据

2.通过下标赋值,即插入数据

3.更新顺序表有效存储长度

void push_back(SeqList *list, ElemType x) {if (list->size >= list->capacity && !Inc(list)) {printf("顺序表空间已满,%d不能尾部插入数据\n", x);return;}list->base[list->size] = x;list->size++;
}

头部插入push_front

插入6 9 1后顺序表中数据顺序为:1 9 6

1.判断有效存储是否小于开辟的内存空间,即判断开辟的空间是否已满,满了不能插入数据

2.size-1即表中最后一个数据的下标,从最后一个数据开始依次向后移动

3.赋值到下标为0的地址,即插入数据

4.更新顺序表有效存储长度

void push_front(SeqList *list, ElemType x) {if (list->size >= list->capacity && !Inc(list)) {printf("顺序表空间已满,%d不能头部插入数据\n", x);return;}for (int i = list->size; i > 0; i--) {list->base[i] = list->base[i - 1];}list->base[0] = x;list->size++;
}

尾部删除pop_back

有顺序表1 6 9进行尾部删除后:1 6

1.判断size是否为0,即表是否为空,空表不能删除数据

2.有效长度减1

void pop_back(SeqList *list) {if (list->size == 0) {printf("顺序表空间已空,不能尾部删除数据\n");return;}list->size--;
}

头部删除pop_front

有顺序表5 6 0进行头部删除后:6 0

1.判断size是否为0,即表是否为空,空表不能删除数据

2.从第二个数据开始,依次往前移动

3.有效长度减1

void pop_front(SeqList *list) {if (list->size == 0) {printf("顺序表空间已空,不能头部删除数据\n");return;}for (int i = 0; i < list->size - 1; i++) {list->base[i] = list->base[i + 1];}list->size--;
}

按位置插入insert_pos

在顺序表5 3 0下标为2的位置插入数据7为:5 3 7 0

1.判断pos是否正确并小于有效存储长度,即判断插入位置是否合法,位置非法不能插入数据

2.判断有效存储是否小于开辟的内存空间,即判断开辟的空间是否已满,满了不能插入数据

3.从最后一个数据开始依次向后移动,直到要插入数据的位置移动结束

4.通过下标赋值,即插入数据

5.更新顺序表有效存储长度

void insert_pos(SeqList *list, int pos, ElemType x) {if (pos < 0 || pos > list->size) {printf("插入数据的位置非法,不能插入数据\n");}if (list->size >= list->capacity && !Inc(list)) {printf("顺序表空间已满,%d不能按位置插入数据\n", x);return;}for (int i = list->size; i > pos; i--) {list->base[i] = list->base[i - 1];}list->base[pos] = x;list->size++;
}

特殊情况:当要插入数据的位置==有效存储长度时,即尾部插入时,不影响效率[特别注意]

按值查找find

(第一个符合条件的)

1.从顺序表第一个数据开始向后遍历

2.每次遍历判断该数据是否是要查找的数据,查找成功返回当前下标

3.遍历结束,即没查到数据,返回-1

int find(SeqList *list, ElemType key) {for (int i = 0; i < list->size; i++) {if (list->base[i] == key)return i;}return -1;
}

按位置删除delete_pos

顺序表5 3 0删除位置为1的数据后:5 0

1.判断pos是否正确并小于有效存储长度,即判断删除位置是否合法,位置非法不能删除数据

2.从要删除的位置开始,依次将后一个数据前移

3.更新顺序表有效存储长度

void delete_pos(SeqList *list, int pos) {if (pos < 0 || pos >= list->size)printf("删除数据的位置非法,不能删除数据\n");for (int i = pos; i < list->size - 1; i++) {list->base[i] = list->base[i + 1];}list->size--;
}

按值删除delete_val

顺序表5 3 0删除值为0的数据后:5 3

1.判断要删除的数据是否存在,即按值查找,存在得到查找到的数据下标,不存在得到-1

2.判断返回值是否是-1,是则数据不存在无法删除,否则按位置删除

void delete_val(SeqList *list, ElemType key) {int pos = find(list, key);if (pos == -1) {printf("要删除的数据不存在\n");return;}delete_pos(list, pos);
}

排序sort(冒泡;升序)

顺序表5 3 0 1 9 4排序后:0 1 3 4 5 9

1.两层遍历,依次比较两个数据,前面数据大于后面数据则交换

void sort(SeqList *list) {for (int i = 0; i < list->size; i++) {for (int j = 0; j < list->size - i - 1; j++) {if (list->base[j] > list->base[j + 1]) {ElemType tmp = list->base[j];list->base[j] = list->base[j + 1];list->base[j + 1] = tmp;}}}
}

逆置resver

顺序表5 3 0 1 9 4逆置后:4 9 1 0 3 5

1.判断顺序表长度是否可进行逆置操作操作,长度为1或0时不需要

2.设置两个整型指针low和high,分别指向第一个数据和最后一个数据,low指针后移,high指针前移,每次将两个指针指向的数据对换,直到low指针大于或等于high指针为止

void resver(SeqList *list) {if (list->size == 0 || list->size == 1)return;int low = 0;int high = list->size - 1;ElemType tmp;while (low < high) {tmp = list->base[low];list->base[low] = list->base[high];list->base[high] = tmp;low++;high--;}
}

清除表clear

void clear(SeqList *list) {list->size = 0;
}

销毁表destroy

void destroy(SeqList *list) {free(list->base);list->base = NULL;list->capacity = 0;list->size = 0;
}

free函数必须和malloc函数同时使用

free只能释放由malloc动态分配在堆内存的内存,直接在主函数定义结构体变量是分配在栈内存里的内存,所以释放不了

合并表merge

表A1 2 5 6,表B3 4 7 9,合并后:1 2 3 4 5 6 9

1.设置iaibic三个整型指针,分别用来遍历表A、B、合并表,开辟存放合并表的内存空间,并判断是否开辟成功

2.同时遍历表A和表B,依次判断指针指向的A、B表的数据大小,将较小的数据放入合并表,每存入一个数据,合并表和被存入的数据所在表的整型指针都向后移一次,直到A、B有一个表遍历完

3.如果其中一个表遍历结束,另一个表还有遍历完的数据,则直接将剩余数据依次存入合并表

4.更新合并表有效存储长度

void merge(SeqList *lt, SeqList *la, SeqList *lb) {lt->capacity = la->size + la->size;lt->base = (ElemType *) malloc(sizeof(ElemType)*lt->capacity);assert(lt->base != NULL);int ia = 0;int ib = 0;int ic = 0;while(ia<la->size && ib<lb->size){if(la->base[ia] < lb->base[ib])lt->base[ic++] = la->base[ia++];elselt->base[ic++] = lb->base[ib++];}while(ia < la->size){lt->base[ic++] = la->base[ia++];}while(ib < lb->size){lt->base[ic++] = lb->base[ib++];}lt->size = la->size + lb->size;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/206746.shtml

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

相关文章

云上业务DDoS与CC攻击防护实践

案例背景&#xff1a;DDoS攻击来势汹汹&#xff0c;云上业务面临威胁 某网络科技有限公司&#xff0c;SaaS化创业公司&#xff0c;业务基于云上开展。其业务主要为各大网站提供安全验证服务&#xff0c;且市场占有率较高&#xff0c;服务客户遍布金融、直播、教育、电商等多个领…

【日常总结】mybatis-plus WHERE BINARY 中文查不出来

目录 一、场景 二、问题 三、原因 四、解决方案 五、拓展&#xff08;全表全字段修改字符集一键更改&#xff09; 准备工作&#xff1a;做好整个库备份 1. 全表一键修改 Stage 1&#xff1a;运行如下查询 Stage 2&#xff1a;复制sql语句 Stage 3&#xff1a;执行即可…

100. 相同的树(Java)

目录 解法&#xff1a; 官方解法&#xff1a; 方法一&#xff1a;深度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 方法二&#xff1a;广度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 给你两棵二叉树的根节点 p 和…

L1-028:判断素数

题目描述 本题的目标很简单&#xff0c;就是判断一个给定的正整数是否素数。 输入格式&#xff1a; 输入在第一行给出一个正整数N&#xff08;≤ 10&#xff09;&#xff0c;随后N行&#xff0c;每行给出一个小于231的需要判断的正整数。 输出格式&#xff1a; 对每个需要判断的…

Kotlin(十五) 高阶函数详解

高阶函数的定义 高阶函数和Lambda的关系是密不可分的。在之前的文章中&#xff0c;我们熟悉了Lambda编程的基础知识&#xff0c;并且掌握了一些与集合相关的函数式API的用法&#xff0c;如map、filter函数等。另外&#xff0c;我们也了解了Kotlin的标准函数&#xff0c;如run、…

vuepress-----22、其他评论方案

vuepress 支持评论 本文讲述 vuepress 站点如何集成评论系统&#xff0c;选型是 valineleancloud, 支持匿名评论&#xff0c;缺点是数据没有存储在自己手里。市面上也有其他的方案, 如 gitalk,vssue 等, 但需要用户登录 github 才能发表评论, 但 github 经常无法连接,导致体验…

[wp]“古剑山”第一届全国大学生网络攻防大赛 Web部分wp

“古剑山”第一届全国大学生网络攻防大赛 群友说是原题杯 哈哈哈哈 我也不懂 我比赛打的少 Web Web | unse 源码&#xff1a; <?phpinclude("./test.php");if(isset($_GET[fun])){if(justafun($_GET[fun])){include($_GET[fun]);}}else{unserialize($_GET[…

使用cmake构建的工程的编译方法

1、克隆项目工程 2、进入到工程目录 3、执行 mkdir build && cd build 4、执行 cmake .. 5、执行 make 执行以上步骤即可完成对cmake编写的工程进行编译 &#xff0c;后面只需执行你的编译结果即可 $ git clone 你想要克隆的代码路径 $ cd 代码文件夹 $ mkdir bu…

测试:SRE

SRE&#xff08;Site Reliability Engineering&#xff0c;站点可靠性工程&#xff09;是一种关注于构建、运行和维护大规模分布式系统的工程学科。它旨在确保系统在各种故障情况下仍然可用、可靠和高效。 SRE的核心目标是通过软件工程的方法来解决系统可靠性问题&#xff0c;…

WPF DataGrid 里面的ToggleButton点击不生效

已解决&#xff1a;根本原因是没写UpdateSourceTriggerPropertyChanged <ToggleButton IsChecked"{Binding PathIsEnabled,ModeTwoWay,UpdateSourceTriggerPropertyChanged}"/> 具体原因参考下面文章&#xff1a;鸣谢作者 WPF 数据集合绑定到DataGrid、ListV…

vmware安装centos7总结

vmware安装centos7总结 文章目录 vmware安装centos7总结一、配置网络&#xff08;桥接模式&#xff09;二、配置yum源&#xff08;连网配置&#xff09;三、可视化界面四、安装Docker五、安装DockerUI 一、配置网络&#xff08;桥接模式&#xff09; 网络连接模式选择桥接模式…

Ubuntu安装nvidia GPU显卡驱动教程

Ubuntu安装nvidia显卡驱动 1.安装前安装必要的依赖 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官网下载对应驱动 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸载原有驱动 sudo apt-get remove --purge nvidi…

深度学习:注意力机制(Attention Mechanism)

1 注意力机制概述 1.1 定义 注意力机制&#xff08;Attention Mechanism&#xff09;是深度学习领域中的一种重要技术&#xff0c;特别是在序列模型如自然语言处理&#xff08;NLP&#xff09;和计算机视觉中。它使模型能够聚焦于输入数据的重要部分&#xff0c;从而提高整体…

孩子都能学会的FPGA:第二十五课——用FPGA实现频率计

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

基于SpringBoot+maven+Mybatis+html慢性病报销系统(源码+数据库)

一、项目简介 本项目是一套基于SpringBootmavenMybatishtml慢性病报销系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&a…

二十一章(网络通信)

计算机网络实现了多台计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是在已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#xff0c;相互之间可以交换数据。编写网络应用程序前&#xff0c;首先必须明确所要使用的网络协议…

C++_命名空间(namespace)

目录 1、namespace的重要性 2、 namespace的定义及作用 2.1 作用域限定符 3、命名空间域与全局域的关系 4、命名空间的嵌套 5、展开命名空间的方法 5.1 特定展开 5.1 部分展开 5.2 全部展开 结语&#xff1a; 前言&#xff1a; C作为c语言的“升级版”&#xff0c;其在…

快速排序的新用法

普通快排 简介 快速排序是一种高效的排序算法&#xff0c;利用分治的思想进行排序。它的基本原理是在待排序的n个数据中任取一个数据为分区标准&#xff0c;把所有小于该排序码的数据移到左边&#xff0c;把所有大于该排序码的数据移到右边&#xff0c;中间放所选记录&#x…

Spring 之 @Cacheable 缓存使用教程

1、Cacheable 指定使用缓存 定义个 Controller &#xff0c;在方法上加上注解 Cacheable&#xff0c;配置要使用哪些缓存&#xff0c;比如 myMapCache 表示一级缓存是 Map&#xff0c;myRedisCache 表示二级缓存是 Redis。并配置缓存 key。 key 由 SPEL 表达式组成&#xff0c…

异常检测 | MATLAB实现BiLSTM(双向长短期记忆神经网络)数据异常检测

异常检测 | MATLAB实现BiLSTM(双向长短期记忆神经网络)数据异常检测 目录 异常检测 | MATLAB实现BiLSTM(双向长短期记忆神经网络)数据异常检测效果一览基本介绍模型准备模型设计参考资料效果一览 基本介绍 训练一个双向 LSTM 自动编码器来检测机器是否正常工作。 自动编码器接受…