顺序表(详解)

1.什么是数据结构

所谓数据结构也就是数据在内存中的储存结构,它有 线性表,队列,栈结构,树结构,图结构等等,顺序表是线性表的一种。

2.物理结构与逻辑结构

物理结构是指一个数据在内存实际的储存空间,逻辑结构是来抽象的描述数据之间有某种联系 举个例子:

比如我说:我们是好朋友是一个整体不能分开,但我们真的是一个整体吗?事实上我们是单个的人,相互独立。而这里说成我们是一个整体只是因为我们存在着某种关系,整体是来描述这种关系的一种说法,实际我们是相互独立的。

我们是一个整体 相当于逻辑结构的描述

我们是独立的个体 相当于物理结构的描述

3.什么是线性表

线性表是指在逻辑结构上是线性的,线性表有静态顺序表,动态顺序表,单链表,双链表等。

而顺序表就相当于数组,它的储存结构和数组相同,在逻辑结构和物理结构上都是线性的静态顺序表就是一个数组,它的大小是在定义的时候就决定好的,不可在程序运行后改变,具有局限性动态顺序表的内存是需要动态开辟的需要用到动态开辟函数,而通过realloc函数可以对它的内存根据需要调节,比较灵活,现在我们主要来学习一下动态顺序表。

静态顺序表定义:

typedef int SLDataType;
typedef struct SeqList
{SLDataType arr[100];int size;//记录arr数组中已储存元素的个数
}SL;

动态顺序表定义:

typedef int SLDataType;
typedef struct SeqList
{SLDataType* arr;int size;//记录arr中已储存元素的个数int capacity;//记录arr申请的空间的大小
}SL;

 4.动态顺序表

4.1.头文件(SeqLish.h)声明:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
#define N 3
typedef int SLDataType;//方便根据需要一次性替换为其他类型
typedef struct SeqList
{SLDataType* arr;int size;//记录arr中已储存元素的个数int capacity;//记录arr申请的空间的大小
}SL;void CSH(SL* ps);//初始化
void PrintSL(SL ps);//输出顺序表
void FreeSL(SL* ps);//顺序表释放内存void CapSL(SL* ps);//根据需要判断是否增容void EndPush(SL* ps, SLDataType x);//尾插
void HeadPush(SL* ps, SLDataType x);//头插
void LocPush(SL* ps, int loc, SLDataType x);//指定位置插入void EndDelete(SL* ps);//尾删
void HeadDelete(SL* ps);//头删
void LocDelete(SL* ps, int loc);//指定位置删除int FindSL(SL* ps, SLDataType x);//数据查找

接下来我们依次来实现以上操作:

每一步为什么这么写都在注释中解释

4.2.初始化:

#include"SeqList.h"
void CSH(SL* ps)
{ps->arr = NULL;//把它置为NULL防止野指针的出现ps->capacity = ps->size = 0;//或memset(ps, 0, sizeof(*ps));
}

4.3.顺序表输出:

void PrintSL(SL* ps)
{assert(ps);//作用: 如果ps是空指针就报出警告并停止运行for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);//有效数据是储存在ps->arr的前p->size个中}
}

4.4.顺序表内存释放:

void FreeSL(SL* ps)
{assert(ps);free(ps->arr);//动态申请的内存需要释放,否则会发生内存泄漏ps->arr = NULL;//释放内存后ps->arr依旧指向原空间,需要置空ps->size = ps->capacity = 0;
}

4.5.判断扩容:

void CapSL(SL* ps)
{assert(ps);if (ps->size == ps->capacity)//若已储存元素的个数等于空间大小,说明内存不足{int Cap = ps->capacity == 0 ? N : ps->capacity * 2;//增容一般增两倍//但是当容量为0时,0乘2仍然等于0,所以分两种情况,N在头文件已定义。SLDataType* Sk = (SLDataType*)realloc(ps->arr, Cap * sizeof(SLDataType));//因为realloc函数在申请内存失败的时候会返回NULL(即会丢失原的数据)//所以用一个Sk来接受,再判断Sk是否为NULL,不为的话就可以赋给ps->arrif (Sk == NULL){perror("ralloc No");//这个函数可以用来打印错误信息,需要包含头文件<errno.h>exit(-1);//该函数用于结束程序的运行}ps->arr = Sk;ps->capacity = Cap;//更新空间大小}
}

4.6.尾插:

void EndPush(SL* ps, SLDataType x)
{CapSL(ps);//只要是插入操作一定要判断是否扩容,后面就不在赘述ps->arr[ps->size] = x;ps->size++;
}

4.7.头插:

void HeadPush(SL* ps, SLDataType x)
{CapSL(ps);for (int i = ps->size; i > 0; i--){    //把数据整体向后移,给头的位置留出空位ps->arr[i] = ps->arr[i - 1];}//或memmove(ps->arr+1, ps->arr, sizeof(SLDataType) * ps->size);ps->arr[0] = x;ps->size++;
}

4.8.指定位置插入:

void LocPush(SL* ps, int loc, SLDataType x)
{CapSL(ps);for (int i = ps->size; i > loc; i--){ps->arr[i] = ps->arr[i - 1];}//或memmove(ps->arr + loc + 1, ps->arr + loc, sizeof(SLDataType) * (ps->size - loc+1));ps->arr[loc] = x;ps->size++;
}

4.9.尾删:

void EndDelete(SL* ps)
{assert(ps);if (ps->size == 0){    //如果顺序表中没有元素就不能再删直接返回return;}ps->size--;
}

4.10.头删:

void HeadDelete(SL* ps)
{assert(ps);for (int i = 0; i < ps->size - 1; i++){    //把后面的数据整体向前移将首元素覆盖ps->arr[i] = ps->arr[i + 1];}//或memmove(ps->arr, ps->arr + 1, sizeof(SLDataType) * (ps->size - 1));ps->size--;
}

4.11.指定位置删除:

void LocDelete(SL* ps, int loc)
{assert(ps);assert(loc >= 0 && loc <= ps->size - 1);//不能超过数据范围for (int i = loc; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}//或memmove(ps->arr + loc, ps->arr + loc + 1, sizeof(SLDataType) * (ps->size - 1 - loc));ps->size--;
}

4.12.数据查找:

int FindSL(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->arr[i]){return i;//找到返回它的下标}}return -1;//找不到返回-1
}

5.原码:

SeqList.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
#define N 3
typedef int SLDataType;
typedef struct SeqList
{SLDataType* arr;int size;//记录arr中已储存元素的个数int capacity;//记录arr申请的空间的大小
}SL;void CSH(SL* ps);//初始化
void PrintSL(SL* ps);//输出顺序表
void FreeSL(SL* ps);//顺序表释放内存void CapSL(SL* ps);//根据需要判断是否增容void EndPush(SL* ps, SLDataType x);//尾插
void HeadPush(SL* ps, SLDataType x);//头插
void LocPush(SL* ps, int loc, SLDataType x);//指定位置插入void EndDelete(SL* ps);//尾删
void HeadDelete(SL* ps);//头删
void LocPush(SL* ps, int loc);//指定位置删除int FindSL(SL* ps, SLDataType x);//数据查找

SeqList.c 文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void CSH(SL* ps)
{ps->arr = NULL;//把它置为NULL防止野指针的出现ps->capacity = ps->size = 0;//或memset(ps, 0, sizeof(*ps));
}
void PrintSL(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}
}
void FreeSL(SL* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->size = ps->capacity = 0;
}
void CapSL(SL* ps)
{assert(ps);if (ps->size == ps->capacity)//若已储存元素的个数等于空间大小,说明内存不足{int Cap = ps->capacity == 0 ? N : ps->capacity * 2;//增容一般增两被//但是当容量为0时0乘任何数都等于0,所以分两种情况,N在头文件已定义。SLDataType* Sk = (SLDataType*)realloc(ps->arr, Cap * sizeof(SLDataType));//因为realloc函数在申请内存失败的时候会返回NULL(即会丢失原的数据)//所以用一个Sk来接受,再判断Sk是否为NULL,不为的话就可以赋给ps->arrif (Sk == NULL){perror("ralloc No");//这个函数可以用来打印错误信息,需要包含头文件<errno.h>exit(-1);//该函数用于结束程序的运行}ps->arr = Sk;ps->capacity = Cap;//更新空间大小}
}
void EndPush(SL* ps, SLDataType x)
{CapSL(ps);//只要是插入操作一定要判断是否扩容后面就不在赘述ps->arr[ps->size] = x;ps->size++;
}
void HeadPush(SL* ps, SLDataType x)
{CapSL(ps);for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}//或memmove(ps->arr+1, ps->arr, sizeof(SLDataType) * ps->size);ps->arr[0] = x;ps->size++;
}
void LocPush(SL* ps, int loc, SLDataType x)
{CapSL(ps);assert(loc >= 0 && loc < ps->size);for (int i = ps->size; i > loc; i--){ps->arr[i] = ps->arr[i - 1];}//或memmove(ps->arr + loc + 1, ps->arr + loc, sizeof(SLDataType) * (ps->size - loc));ps->arr[loc] = x;ps->size++;
}
void EndDelete(SL* ps)
{assert(ps);if (ps->size == 0){return;}ps->size--;
}
void HeadDelete(SL* ps)
{assert(ps);for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}//或memmove(ps->arr, ps->arr + 1, sizeof(SLDataType) * (ps->size - 1));ps->size--;
}
void LocDelete(SL* ps, int loc)
{assert(ps);assert(loc >= 0 && loc < ps->size );for (int i = loc; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}//或memmove(ps->arr + loc, ps->arr + loc + 1, sizeof(SLDataType) * (ps->size - 1 - loc));ps->size--;
}
int FindSL(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->arr[i]){return i;}}return -1;
}

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
int main()
{SL sk;CSH(&sk);//HeadPush(&sk, 1);HeadPush(&sk, 2);HeadPush(&sk, 3);HeadPush(&sk, 4);//EndPush(&sk, 4);EndPush(&sk, 5);//HeadDelete(&sk);EndDelete(&sk);//LocPush(&sk, 1, 90);LocPush(&sk, 3, 10);//LocDelete(&sk,2);//PrintSL(&sk);int ret = FindSL(&sk, 90);printf("\n%d", ret);FreeSL(&sk);return 0;
}

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

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

相关文章

C++面向对象程序设计 - 运算符重载

函数重载就是对一个已有的函数赋予新的含义&#xff0c;使之实现新的功能。因此一个函数名就可以用来代表不同功能的函数&#xff0c;也就是一名多用。运算符也可以重载&#xff0c;即运算符重载&#xff08;operator overloading&#xff09;。 一、运算符重载的方法 运算符重…

indexDB 大图缓存

背景 最近在项目中遇到了一个问题&#xff1a;由于大屏背景图加载速度过慢&#xff0c;导致页面黑屏时间过长&#xff0c;影响了用户的体验。从下图可以看出加载耗时将近一分钟 IndexDB 主要的想法就是利用indexDB去做缓存&#xff0c;优化加载速度&#xff1b;在这之前&am…

在选择试验台底座时,应注意哪些问题——河北北重

在选择试验台底座时&#xff0c;应注意以下几个方面&#xff1a; 底座尺寸和承载能力&#xff1a;底座的尺寸和承载能力应与试验台的尺寸和所需承载的设备重量相匹配&#xff0c;确保底座能够稳定承载试验台和设备。 材料和质量&#xff1a;底座的材料应具有足够的强度和耐久性…

软件测试之【合理的利用GPT来辅助软件测试一】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言GPT的原理及技巧GPT辅助接口自动化测试 前言 在编程基础栏目中&#xff…

Kafak详解(1)

简介 消息队列 为什么要有消息队列 图-1 消息队列的使用 消息队列 1)消息Message&#xff1a;网络中的两台计算机或者两个通讯设备之间传递的数据。例如说&#xff1a;文本、音乐、视频等内容。 2)队列Queue&#xff1a;一种特殊的线性表(数据元素首尾相接)&#xff0c;特…

2024平替电容笔买哪个品牌好?iPad电容笔全能榜单热门款TOP5分享!

2024年&#xff0c;随着科技的不断发展和消费者对生活品质的追求&#xff0c;电容笔作为一种创新的无纸化工具&#xff0c;逐渐走进人们的生活和工作中。然而&#xff0c;在电容笔市场的繁荣背后&#xff0c;也隐藏着品质良莠不齐的现象。众多品牌为了追求利润&#xff0c;推出…

JS----随机数字,字符,数组

随机数字 function random(min 0, max 100) {if (min > 0 && max > 0 && max > min) {const gab max - min 1return Math.floor(Math.random() * gab min)}return 0 }输入格式 随机字符 function randomStr (len 32) {var s for (; s.lengt…

电力调度自动化系统由什么构成?

电力调度自动化系统由什么构成&#xff1f; 电力调度自动化系统通过数据采集与传输、数据处理与存储、监视与控制、优化与决策、通信网络和系统应用软件等构成&#xff0c;实现对电力系统的监控、控制和优化。 电力调度自动化系统是一种集成了计算机技术、通信技术、自动化技术…

SpringBoot下载Excel模板功能

目录 一、前端只需要填写一个a标签调用一下后端接口即可 二、后端 2.1 准备一个excel模板 &#xff0c;将其复制到resource目录下的templates文件夹下 2.2 接着复制下列代码即可 三、运行效果 一、前端只需要填写一个a标签调用一下后端接口即可 1.1 先代理一下防止跨域 e…

40-50W 1.5KVDC 隔离 宽电压输入 DC/DC 电源模块 ——TP40(50)DC 系列

TP40(50)DC系列电源模块额定输出功率为40-50W、应用于2:1、4&#xff1a;1电压输入范围 9V-18V、18V-36V、36V-75V、9V-36V、18V-75V的输入电压环境&#xff0c;输出电压精度可达1%&#xff0c;可广泛应用于通信、铁路、自动化以及仪器仪表等行业。

【系统分析师】软件工程

文章目录 1、信息系统生命周期2、软件开发模型2.1 原型及其演化2.2 增量模型和螺旋模型2.3 V模型、喷泉模型、快速应用开发2.4 构件组装模型2.5 统一过程-UP2.6 敏捷方法 3、逆向工程4、净室软件工程 【写在前面】 记录了一系列【系统分析师】文章&#xff0c;点击下面的链接&a…

【鸿蒙开发】后台任务

1. 功能介绍 设备返回主界面、锁屏、应用切换等操作会使应用退至后台。 2. 后台任务类型 OpenHarmony标准系统支持规范内受约束的后台任务&#xff0c;包括短时任务、长时任务、延迟任务、代理提醒和能效资源。 开发者可以根据如下功能介绍&#xff0c;选择合适的后台任务以…

软件测试架构体系之软件测试基本流程图

前言&#xff1a; 采用通用的测试流程&#xff0c;能高效、高质量的完成软件测试工作&#xff0c;有助于减少沟通成本&#xff0c;对各阶段产出有明确认知等等。最终目标&#xff1a;实现软件测试规范化、标准化。以下为非通用标准&#xff0c;仅供大家参考。 一、软件测试流…

DSView Windows平台编译

在Windows平台编译开源逻辑分析仪软件DSView&#xff0c;因官方没有公布DSView Windows平台源码&#xff0c;主要解决Windows平台以下问题&#xff1a; libusb_get_pollfds不支持Windows平台&#xff0c;导致无法采集数据插入设备后&#xff0c;无法自动识别设备&#xff0c;U…

vue3中web前端JS动画案例(一)

上述案例主要使用定时器&#xff0c;和绝对定位产生动画 <script setup> import { ref, onMounted, watch } from vue // ----------------------- 01 js 动画介绍--------------------- // 1、匀速运动 // 2、缓动运动&#xff08;常见&#xff09; // 3、透明度运动 //…

【深度学习实战(18)】torch模型转onnx模型,使用netron根据查看onnx结构

一、ONNX介绍 简单来说&#xff0c;可以把ONNX当做一个中间格式。绝大多数的机器学习/深度学习框架都可以将自身的模型转换成ONNX&#xff0c;同样也能把ONNX转换成自身框架的格式&#xff0c;如下图所示。 二、转ONNX模型代码 import torch import torchvision.models as …

利用selenium发挥vip残存的价值

历史版本谷歌浏览器驱动下载地址 https://chromedriver.storage.googleapis.com/index.html 找到与你电脑当前谷歌浏览器版本一致的驱动然后下载下来(大版本一致即可)。我本地版本是 99.0.04844.51 我这里把 chromedriver 放到 /usr/local/bin 下面了。 启动测试窗口 这里需要…

[tkinter实现]汉字笔顺小软件

软件简介 本软件旨在帮助小学生通过互动式学习掌握汉字的基本笔画和笔顺。软件采用Tkinter库构建&#xff0c;提供了一个用户友好的图形界面&#xff0c;适合小学生使用。 主要功能&#xff1a; 汉字展示&#xff1a;软件能够展示单个汉字&#xff0c;并以动画形式演示其标准…

网络基础(day2)

一、进制转换 在计算机底层通信&#xff0c;以及数据处理都是采用二进制&#xff0c;也就是1和0传递信息&#xff0c;因此进制转换是非常重要的知识点。 十进制&#xff08;DEC&#xff09;【逢十进一 】案例&#xff1a; 按权展开 权&#xff1a;10的N次幂123123二进制&am…

羊大师分析,夏季羊奶的适合人群有哪些?

羊大师分析&#xff0c;夏季羊奶的适合人群有哪些&#xff1f; 夏季羊奶的适合人群相当广泛&#xff0c;主要包括以下几类人群&#xff1a; 生长发育中的孩子&#xff1a;羊奶富含营养&#xff0c;特别是蛋白质和矿物质&#xff0c;对孩子的生长发育有积极的促进作用。 中老年…