顺序表的实现(数据结构)——C语言
目录
1.结构与概念
2.分类
3 动态顺序表的实现
SeqList.h
SeqList.c
创建SLInit:
尾插SLPushBack以及SLCheak(检查空间是否足够):
头插SLPushFront:
尾删SLPopBack
头删SLPopFront
查找指定元素SLFind
指定位置插入SLInsert
指定位置删除SLEarse
打印元素SLPrint
销毁SLDestory
整体代码:
SeqList.h
SeqList.c
1.结构与概念
概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。顺序表的底层其实就是顺序表,只是将数组进行了了一下包装。
2.分类
静态顺序表:使⽤定⻓数组存储元素;动态顺序表:空间不够用时,可以增加空间,静态顺序表缺陷:空间给少了不够⽤,给多了造成空间浪费,所以这里实现的是动态顺序表。
3 动态顺序表的实现
这里先还是创建三个文件,即test.c,SeqList.c,SeqList.h,分别是测试文件,顺序表的头文件,顺序表的函数实现文件,首先要在头文件中定义顺序表的结构体类型,结构体中有定义的数组类型,数据个数,以及空间大小,这里的数据类型DataType,在前面可以直接通过更改typedef后面直接修改整个的数据类型,这里以int类型为例:
typedef int DataType;typedef struct SeqList
{DataType* arr;int size ;int capacity ;
}SL;
还有就是头文件中肯定要包含各种头文件,这样在其他文件中直接包含“SeqList.h”就可以直接是用了,以及后面要实现的增删查改的操作的的函数头文件都包含在内:
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DataType;typedef struct SeqList
{DataType* arr;int size ;int capacity ;
}SL;void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
void SLCheak(SL* ps);void SLPushback(SL* ps,DataType x);
void SLPushFront(SL* ps, DataType x);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos,DataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, DataType x);
SeqList.c
在这个文件中就是实现增删查改的各种函数,首先第一个为创建一个顺序表
创建SLInit:
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}
初始情况下,数组指向空,空间大小,数据个数为0;还有注意这里要传一级指针,因为这里要使ps发生改变,后面的函数实现基本都要传一级指针;
尾插SLPushBack以及SLCheak(检查空间是否足够):
void SLCheak(SL* ps)
{if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;DataType* tmp = (DataType*)realloc(ps->arr, newcapacity*sizeof(DataType));if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}
}void SLPushback(SL* ps, DataType x)
{assert(ps);SLCheak(ps);ps->arr[ps->size] = x;ps->size++;
}
因为这里实现插入操作,第一考虑的是,空间是否足够可以插入,所以这里实现了一个检查空间是否足够的函数SLCheak,如果空间够,就不进行任何操作,如果不够就要申请空间,申请空间每次为上次的两倍,如果是0的话,就附一个初值为4,申请空间时要判断是否申请成功,这里使用realloc函数,申请成功后再给ps;
尾差操作则是先判断ps是否为空后,直接在数组最后一个位置放入x,然后数据个数ps->size再++;
头插SLPushFront:
void SLPushFront(SL* ps, DataType x)
{assert(ps);SLCheak(ps);for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps ->size++;
}
第一步任然是判断ps是否为空,以及空间大小是否足够,因为这里要在第一个位置插入,所以数组整体都要向后移动一位,这里就是一个for循环,为了避免数据被覆盖,从最后一个位置元素先向后移动再依次直到第一个元素被移到第二个位置结束,然后再插入元素x,ps->size再++;
尾删SLPopBack
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}
尾删即从最后删除一个元素,这里可以直接简单化处理,直接将ps->size--,这样就访问不到原本size-1位置的数据,相当于是把最后一个元素删掉了;
头删SLPopFront
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
头删即从第一个元素删除,这里可以直接将后面的元素依次先前移动一位,直接将第一个元素覆盖,这里要注意循环介质的条件,是ps->size-1,再将ps->size--即可;
查找指定元素SLFind
int SLFind(SL* ps, DataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}
这里就是遍历数组,与x比较,找到就返回就行了;
指定位置插入SLInsert
void SLInsert(SL* ps, int pos, DataType x)
{assert(ps && pos < ps->size && pos >= 0);SLCheak(ps);for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}
这里和头插有点相似,这里主要注意结束循环是i>pos,就是将pos之后的元素向后移动一位,再在pos位置插入x,元素个数ps->size++;
指定位置删除SLEarse
void SLErase(SL* ps, int pos)
{assert(ps && pos < ps->size && pos >= 0);for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
和头删有异曲同工之妙,也是注意循环结束条件是ps->size-1,将pos之后的元素向前移动一位,然后元素个数ps->size--即可;
打印元素SLPrint
void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
遍历数组,依次输出即可;
销毁SLDestory
void SLDestroy(SL* ps)
{if (ps->arr != NULL){ps->arr = NULL;}ps->size = 0;ps->capacity = 0;
}
将数组置为NULL,以及空间和元素个数都置为0;
整体代码:
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DataType;typedef struct SeqList
{DataType* arr;int size ;int capacity ;
}SL;void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
void SLCheak(SL* ps);void SLPushback(SL* ps,DataType x);
void SLPushFront(SL* ps, DataType x);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos,DataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, DataType x);
SeqList.c
#include"SeqList.h"void SLInit(SL* ps)
{ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}void SLDestroy(SL* ps)
{if (ps->arr != NULL){ps->arr = NULL;}ps->size = 0;ps->capacity = 0;
}void SLCheak(SL* ps)
{if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;DataType* tmp = (DataType*)realloc(ps->arr, newcapacity*sizeof(DataType));if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}
}void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}void SLPushback(SL* ps, DataType x)
{assert(ps);SLCheak(ps);ps->arr[ps->size] = x;ps->size++;
}void SLPushFront(SL* ps, DataType x)
{assert(ps);SLCheak(ps);for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps ->size++;
}void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}void SLInsert(SL* ps, int pos, DataType x)
{assert(ps && pos < ps->size && pos >= 0);SLCheak(ps);for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}void SLErase(SL* ps, int pos)
{assert(ps && pos < ps->size && pos >= 0);for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}int SLFind(SL* ps, DataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}相关文章:
顺序表的实现(数据结构)——C语言
目录 1.结构与概念 2.分类 3 动态顺序表的实现 SeqList.h SeqList.c 创建SLInit: 尾插SLPushBack以及SLCheak(检查空间是否足够): 头插SLPushFront: 尾删SLPopBack 头删SLPopFront 查找指定元素SLFind 指定…...
【VUE】Vue中 computed计算属性和watch侦听器的区别
核心功能不同 computed 是一个计算属性,其核心功能是基于已有的数据属性计算得出新的属性值。当某个依赖的数据发生变化时,computed 会自动重新计算并更新自己的值。因此,可以将 computed 看做是一种“派生状态”。 watch 是一个观察者函数&…...
linux线程 | 同步与互斥 | 深度学习与理解同步
前言:本节内容主要讲解linux下的同步问题。 同步问题是保证数据安全的情况下,让我们的线程访问具有一定的顺序性。 线程安全就规定了它必须是在加锁的场景下的!!那么, 具体什么是同步问题, 我们加下来看看吧…...
Tkinter Frame布局笔记--做一个简易的计算器
#encodingutf-8 import tkinter import re import tkinter.messagebox import tkinter.simpledialog import sys import os def get_resources_path(relative_path):if getattr(sys,frozen, False):base_pathsys._MEIPASS#获取临时文件else:base_pathos.path.dirname(".&q…...
算法专题八: 链表
目录 链表1. 链表的常用技巧和操作总结2. 两数相加3. 两两交换链表中的节点4. 重排链表5. 合并K个升序链表6. K个一组翻转链表 链表 1. 链表的常用技巧和操作总结 常用技巧 画图!!! 更加直观形象, 便于我们理解引入虚拟头节点, 方便我们对链表的操作, 减少我们对边界情况的考…...
MySQL中关于NULL值的六大坑!你被坑过吗?
NULL值是我们在开发过程中的老朋友了,但是这个老朋友在MySQL中有很多坑,我通过这篇文章来总结分享一下,欢迎大家在评论区分享你的看法和踩坑经历。 1、NULL不等于NULL 在MySQL中,执行以下SQL会返回NULL 假如t表有以下数据&#…...
学生学习动机测试:激发潜能,引领未来
学习动机、学习兴趣和学习目标制定是影响学生学习成效的三个关键因素。通过对学生学习动机的测试,我们可以深入了解学生的学习状态,进而采取针对性的措施,激发他们的学习潜能,引导他们走向更加光明的未来。本文将从学习动机、学习兴趣和学习目标制定三个方面,详细探讨学生…...
基于SSM党务政务服务热线管理系统的设计
管理员账户功能包括:系统首页,个人中心,用户管理,部门管理,办事信息管理,信息记录管理,系统管理 前台账号功能包括:系统首页,个人中心,部门,信息…...
OSI参考模型详解:初学者指南与实践案例
OSI参考模型详解:初学者指南与实践案例 OSI(Open System Interconnect)参考模型是一个由国际标准化组织(ISO)提出的七层网络分层模型,它为全球所有互联计算机系统提供了一个通用的通信框架,解决…...
S7-200 SMART 与 S7-1200 之间 TCP 通信— S7-200 SMART 作为服务器
TCP 协议通信 TCP 通信为面向连接的通信,需要双方都调用指令以建立连接及交换数据。S7-200 SMART 与 S7-1200 通过 TCP 通信,在 S7-1200 调用 T-block 指令 ( TCON, TDISCON, TSEND, TRCV ) ,在 S7-200 SMART 调用 Open User Communication …...
Java @RequestPart注解:同时实现文件上传与JSON对象传参
RequestPart注解:用于处理multipart/form-data请求的一部分,通常用于文件上传或者处理表单中的字段。 java后端举例: PostMapping("/fileTest")public AjaxResult fileTest(RequestPart("file") MultipartFile file,Req…...
深度学习基础知识-02 数据预处理
深度学习的数据预处理通常包括: 1.数据清洗:去除错误或不完整的数据。 2.归一化:调整数据范围,如将像素值缩放到0-1。 3.数据增强:通过旋转、缩放等方法增加数据多样性。 4.数据划分:将数据分为训练集、验证…...
【CTF刷题9】2024.10.19
[MoeCTF 2021]babyRCE 考点:关键词过滤(绕过方法参考往期博客) 来源:nssctf <?php$rce $_GET[rce]; if (isset($rce)) {if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\|\%|\&g…...
WPF中的Setter
在 WPF (Windows Presentation Foundation) 中,Setter 是一个定义控件属性值的标记,通常用在 Style 或 Template 中。Setter 用于指定当某些条件满足时,控件的属性应该如何设置。以下是 Setter 的一些关键点: 属性设置:…...
RabbitMQ下载与配置
安装Erlang Erlang 下载地址如下: https://erlang.org/download/otp_versions_tree.html 安装 RabbitMQ RabbitMQ 下载地址如下: https://www.rabbitmq.com/install-windows.html 查看服务,服务已经正常启动 打开Command Prompt 输入rabb…...
【数据结构与算法】力扣 54. 螺旋矩阵
问题描述 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入: matrix [[1,2,3],[4,5,6],[7,8,9]] 输出: [1,2,3,6,9,8,7,4,5]示例 2: 输入: ma…...
速通不了的人工智能
下面是一个详细且系统的人工智能学习框架,涵盖了从基础理论到实际应用的各个方面。这个框架包括理论学习、编程实践、项目实战和资源推荐。为了帮助你更好地理解和应用,我会提供一些具体的代码示例。 人工智能学习框架 1. 基础理论 1.1 数学基础 线性代数:向量、矩阵、特…...
微信新功能上线,找工作也能“附近”搞定
大家好,我是小悟 你们听说了吗?微信又双叒叕出新功能啦!这次可不是什么微整形、小游戏之类的小打小闹,而是实实在在的大招——查找附近的工作!没错,你没听错,就是那个在你家门口就能找到工作的…...
CANoe与C#联合仿真方案
引言 CANoe作为一款强大的网络仿真工具,能够模拟各种通信协议,尤其是在汽车领域的CAN、LIN、Ethernet等协议。而C#作为一种广泛使用的编程语言,能够为CANoe提供灵活的用户界面和逻辑控制。本文将探讨如何将CANoe与C#结合,实现高效的联合仿真方案。 1. 系统架构 联合仿真…...
公交信息在线查询系统|基于java和小程序的公交信息在线查询系统小程序设计与实现(源码+数据库+文档)
公交信息在线查询系统小程序 目录 基于java和小程序的公交信息在线查询系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
