当前位置: 首页 > news >正文

数据结构:顺序表(C实现)

在这里插入图片描述

个人主页 水月梦镜花
个人专栏 C语言 ,数据结构


文章目录

  • 一、顺序表
  • 二、实现思路
    • 1.存储结构
    • 2.初始化顺序表(SeqListInit)
    • 3.销毁顺序表(SeqListDestroty)
    • 4.打印顺序表(SeqListPrint)
    • 5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)
    • 6.顺序表头插(SeqLsitPushFront)
    • 7.顺序表尾删(SeqListPopBack)
    • 8.顺序表头删(SeqListPopFront)
    • 9.顺序表查找(SeqListFind)
    • 10.在pos位置前插入元素(SeqListInsert)
    • 11.删除pos位置的值(SeqListErase)
  • 三、代码实现
  • 总结


一、顺序表

顺序表是用一段物理结构连续的存储单元依次存储数据元素的线性结构,一般采用数组存储。
顺序表一般分为两种:

  • 静态顺序表:使用定长数组实现
  • 动态顺数表:使用动态开辟的数组实现

本篇文章,顺序表是使用动态开辟的数组实现(动态顺序表)。要实现的功能如下:

//初始化顺序表
void SeqListInit(SeqList* ps);//销毁顺序表
void SeqListDestroty(SeqList* ps);//打印顺序表
void SeqListPrint(SeqList* ps);//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDateType x);//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDateType x);//顺序表尾删
void SeqListPopBack(SeqList* ps);//顺序表头删
void SeqListPopFront(SeqList* ps);//顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDateType x);//删除pos位置的值
void SeqListErase(SeqList* ps, int pos);//检查容量
void SeqListCheckCapacity(SeqList* ps);

二、实现思路

画图理解起来更佳!!!

1.存储结构

我们重命名int类型为SLDataType,方便以后我们修改顺序表存储元素的类型。
指针data指向动态开辟的空间,变量sz记录有效的数据元素,变量capacity记录动态开辟空间的大小。

typedef int SLDataType;typedef struct SeqList
{SLDataType* data;int sz;int capacity;
}SeqList;

2.初始化顺序表(SeqListInit)

动态开辟一块空间,用data指针保存空间首地址。
此时data指向空间中有效元素为0,使sz == 0,变量capacity在等于此时开辟空间的大小。

#define SIZE 4void SeqListInit(SeqList* ps)
{ps->data = (SLDataType*)malloc(sizeof(SLDataType) * SIZE);if (ps->data == NULL){perror("malloc");exit(-1);}ps->sz = 0;ps->capacity = SIZE;
}

3.销毁顺序表(SeqListDestroty)

free所开辟的空间,使data == NULL,此时数据有效元素为0,空间大小为0,那么sz = 0,capacity = 0;

//销毁顺序表
void SeqListDestroty(SeqList* ps)
{assert(ps);//free(ps);free(ps->data);ps->data = NULL;ps->sz = 0;ps->capacity = 0;
}

4.打印顺序表(SeqListPrint)

这个函数非常简单,只要遍历一遍所开辟的空间即可,注意范围是(0,sz)。

//打印顺序表
void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->sz; i++){printf("%d ", ps->data[i]);}printf("\n");}

5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)

每次加入数据时,我们要先检查空间大小是否充足,再加入数据

  • 检查容量
    在尾插数据前,要检查空间大小是否充足(sz == capacity),如果空间大小不够,要扩大空间大小,capacity记录新的空间大小。

  • 尾插元素
    变量sz不仅代表空间有效元素个数,也代表了新数据元素将要放入的位置。所以尾插元素,只要空间大小充足,那么在data[sz]处放入数据即可,不要忘记sz要加一。

//检查容量
void SeqListCheckCapacity(SeqList* ps)
{SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc");exit(-1);}ps->data = tmp;ps->capacity *= 2;
}//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}ps->data[ps->sz] = x;ps->sz++;
}

6.顺序表头插(SeqLsitPushFront)

顺序表除了尾插,尾删不用挪到数据,其它的增删都要挪到数据。
头插数据,要先检查空间大小,再向后挪到数据,将数据放入data[0]处,sz在加一。

//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDataType x)
{assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > 0){ps->data[end] = ps->data[end - 1];end--;}ps->data[0] = x;ps->sz++;
}

7.顺序表尾删(SeqListPopBack)

变量sz代表有效数据的个数,那么只要sz减一,就代表最后一个数据被删除了。

//顺序表尾删
void SeqListPopBack(SeqList* ps)
{assert(ps);assert(ps->sz != 0);ps->sz--;
}

8.顺序表头删(SeqListPopFront)

头删数据,要将数据从后向前挪到,覆盖掉第一个数据,sz要减一。

//顺序表头删
void SeqListPopFront(SeqList* ps)
{assert(ps);assert(ps->sz != 0);for (int i = 0; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}

9.顺序表查找(SeqListFind)

遍历一遍动态开辟的数组,如果找到了就放回下标,没有就放回-1。

//顺序表查找
int SeqListFind(SeqList* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->sz; i++){if (ps->data[i] == x){return i;}}return -1;
}

10.在pos位置前插入元素(SeqListInsert)

要先检查空间容量是否充足和要插入的位置是否合法(要在顺序表的有效数据内),再将pos下标后的数据向后挪到,将数据放入data[pos]处,sz加一。
这个函数思路简单,但要注意下面两点:

  • 如果pos == 0,不就是要在顺序表第一个元素前插入元素,不就是顺序表的头插。
  • 如果pos == sz,我们知道sz还表示下一个数据要放入的位置,那么我在下一个数据要放入的位置前插入元素,不就是顺序表的尾插。

理解这点后,我们以后的头插,尾插都可以用该函数复用。方便我们手撕顺序表

//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->sz);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > pos){ps->data[end] = ps->data[end - 1];end--;}ps->data[pos] = x;ps->sz++;
}

11.删除pos位置的值(SeqListErase)

删除pos位置处的数据,先检查pos的合法性(要属于[0,sz-1]),要将数据从后向前挪到数据,sz减一。
这个函数思路简单,但要注意下面两点:

  • 如果pos == 0,不就是要删除第一个数据,不就是头删。
  • 如果pos == sz - 1,不就是要删除最后一个数据,不就是尾删。

所以对于尾删,头删函数而言,我们也可以使用该函数复用。

//删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->sz);for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}

三、代码实现

头删,头插,尾删,尾插我都复用了SeqListInsert和SeqListErase。
SeqList.h 文件存放有关函数的声明以及结构体的声明
SeqList.c 文件存放函数的定义

//SeqList.h 文件#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#define SIZE 4typedef int SLDataType;typedef struct SeqList
{SLDataType* data;int sz;int capacity;
}SeqList;//初始化顺序表
void SeqListInit(SeqList* ps);//销毁顺序表
void SeqListDestroty(SeqList* ps);//打印顺序表
void SeqListPrint(SeqList* ps);//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDateType x);//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDateType x);//顺序表尾删
void SeqListPopBack(SeqList* ps);//顺序表头删
void SeqListPopFront(SeqList* ps);//顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDateType x);//删除pos位置的值
void SeqListErase(SeqList* ps, int pos);//检查容量
void SeqListCheckCapacity(SeqList* ps);
//SeqList.c 文件#include "SeqList.h"//初始化顺序表
void SeqListInit(SeqList* ps)
{ps->data = (SLDataType*)malloc(sizeof(SLDataType) * SIZE);if (ps->data == NULL){perror("malloc");exit(-1);}ps->sz = 0;ps->capacity = SIZE;
}//检查容量
void SeqListCheckCapacity(SeqList* ps)
{SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc");exit(-1);}ps->data = tmp;ps->capacity *= 2;
}//顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{/*assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}ps->data[ps->sz] = x;ps->sz++;*/SeqListInsert(ps, ps->sz, x);
}//打印顺序表
void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->sz; i++){printf("%d ", ps->data[i]);}printf("\n");}//销毁顺序表
void SeqListDestroty(SeqList* ps)
{assert(ps);//free(ps);free(ps->data);ps->data = NULL;ps->sz = 0;ps->capacity = 0;
}//顺序表头插
void SeqLsitPushFront(SeqList* ps, SLDataType x)
{/*assert(ps);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > 0){ps->data[end] = ps->data[end - 1];end--;}ps->data[0] = x;ps->sz++;*/SeqListInsert(ps, 0, x);
}//顺序表尾删
void SeqListPopBack(SeqList* ps)
{/*assert(ps);assert(ps->sz != 0);ps->sz--;*/SeqListErase(ps, ps->sz - 1);
}//顺序表头删
void SeqListPopFront(SeqList* ps)
{/*assert(ps);assert(ps->sz != 0);for (int i = 0; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;*/SeqListErase(ps, 0);
}//顺序表查找
int SeqListFind(SeqList* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->sz; i++){if (ps->data[i] == x){return i;}}return -1;
}//在pos位置前插入元素
void SeqListInsert(SeqList* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->sz);if (ps->sz == ps->capacity){SeqListCheckCapacity(ps);}int end = ps->sz;while (end > pos){ps->data[end] = ps->data[end - 1];end--;}ps->data[pos] = x;ps->sz++;
}//删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->sz);for (int i = pos; i < ps->sz - 1; i++){ps->data[i] = ps->data[i + 1];}ps->sz--;
}

总结

以上就是顺序表的实现。谢谢支持!!!

在这里插入图片描述

相关文章:

数据结构:顺序表(C实现)

个人主页 水月梦镜花 个人专栏 C语言 &#xff0c;数据结构 文章目录 一、顺序表二、实现思路1.存储结构2.初始化顺序表(SeqListInit)3.销毁顺序表(SeqListDestroty)4.打印顺序表(SeqListPrint)5.顺序表尾插(SeqListPushBack)and检查容量(SeqListCheckCapacity)6.顺序表头插(Se…...

素描基础知识

素描基础入门 1.基础线条 1.1 握笔姿势及长线条 2.排线 2.1 不同姿势画排线 2.1.1 姿势画排线 2.1.2 用手腕画排线 2.1.3 小拇指画排线 2.1.4 叠加排线 2.1.5交叉排线 2.2 纸张擦法 2.3 排线学习榜样 2.4 四种常见的排线 3、定向连线 4、一点透视 4.1 透视的规律 4.2 焦点透视…...

【Chat GPT】用 ChatGPT 运行 Python

前言 ChatGPT 是一个基于 GPT-2 模型的人工智能聊天机器人&#xff0c;它可以进行智能对话&#xff0c;同时还支持 Python 编程语言的运行&#xff0c;可以通过 API 接口进行调用。本文将介绍如何使用 ChatGPT 运行 Python 代码&#xff0c;并提供一个实际代码案例。 ChatGPT …...

cartographer发布畸变矫正后的scan数据

实现方式&#xff1a; 模仿源代码&#xff0c;在cartographer_ros写一个函数&#xff0c;以函数指针的方式传入cartographer后端&#xff0c;然后接收矫正后的scan数据&#xff0c;然后按照话题laserScan发布出来。 需要同时发布点云强度信息的&#xff0c;还要自己添加含有强度…...

Idea中git push to origin/master was rejected错误解决方案

Idea中git push to origin/master was rejected错误解决方案 问题描述解决方法 问题描述 idea开发中,需要将项目发布到gitee上,在gitee上创建仓库后,通过idea中git推送项目代码提示: push to origin/master was rejected 解决方法 gitee创建仓库时创建了README.md文件,本地…...

docker版jxTMS使用指南:自定义频率型动态管控

本文讲解4.4版jxTMS中如何自行定义一个频率型的动态管控&#xff0c;整个系列的文章请查看&#xff1a;docker版jxTMS使用指南&#xff1a;4.4版升级内容 docker版本的使用&#xff0c;请查看&#xff1a;docker版jxTMS使用指南 4.0版jxTMS的说明&#xff0c;请查看&#xff…...

【Docker】初识Docker以及Docker安装与阿里云镜像配置

目录 一、初识Docker 二、安装Docker 三、Docker架构 四、配置Docker镜像加速器 一、初识Docker Docker是一个开源的应用容器引擎&#xff0c;诞生于2013年&#xff0c;基于Go语言实现&#xff0c;dotCloud公司出品&#xff0c;Docker开源让开发者打包他们的应用以及依赖包到…...

C语言:动态内存管理

文章目录 一、动态内存函数1. malloc2. calloc3. realloc4. free 二、常见的错误1.malloc或calloc开辟的空间未检查2.越界访问3.对非malloc和calloc开辟的空间&#xff0c;用free释放4.对同一块动态内存多次释放5.用free释放动态内存的一部分 三、通讯录(动态版本改写)总结 一、…...

如何往MySQL中插入100万条数据?

需求 现在有一个 数据量 为100万的数据样本 100w_data.sql 其数据格式如下&#xff0c;截取最后十条数据 999991,XxGdnLZObA999991,XxGdnLZObA,XxGdnLZObA,2020-3-18,1 999992,TBBchSKobC999992,TBBchSKobC,TBBchSKobC,2020-9-8,2 999993,rfwgLkYhUz999993,rfwgLkYhUz,rfwgLk…...

IntelliJ IDEA 2023.2 最新变化

主要更新 AI Assistant 限定访问 Ultimate 在此版本中&#xff0c;我们为 IntelliJ IDEA 引入了一项重要补充 – AI Assistant。 AI Assistant 当前具备一组由 AI 提供支持的初始功能&#xff0c;提供集成式 AI 聊天&#xff0c;可以完成一些任务&#xff0c;例如自动编写文档…...

1300*B. T-primes

解析&#xff1a; 有且只有三个因数&#xff0c;当且仅当&#xff0c;完全平方数并且sqrt&#xff08;n&#xff09;为素数 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N1e55; ll t,n; bool prime(ll x){if(x<2) return 0;for(int…...

重新C++系列之运算符重载

一、什么是运算符重载 简单来讲就是对运算符赋予新的意义&#xff0c;但是又不能改变原有的含义&#xff0c;它本身也就是一个函数。运算符重载的本质是以函数的方式来体现。 二、运算符重载有几种 1、按照作用域来划分&#xff0c;有全局操作符重载函数和成员函数操作符重载函…...

kotlin异常处理try-catch-finally

kotlin异常处理try-catch-finally fun main(args: Array<String>) {try {println("a")} catch (e: Exception) {//异常捕获println("a-catch: $e")} finally {//善后&#xff0c;无论是否异常&#xff0c;都会执行println("a-finally")}t…...

Pytorch在cuda、AMD DirectML和AMD CPU下性能比较

一、测试环境 CUDA环境: i7-8550u 16G DDR4 2133MHz nVidia MX150 2GB AMD DirectML环境: Ryzen 5 5600G 32G DDR4 3200MHz Vega7 4GB AMD 纯CPU环境&#xff1a;Ryzen 5 5600G 32G DDR4 3200MHz 其他硬件配置的硬盘、电源均一致。Pytorch版本为2.0.0&#xff0c;Pyt…...

哈工大计算机网络课程局域网详解之:交换机概念

哈工大计算机网络课程局域网详解之&#xff1a;交换机概念 文章目录 哈工大计算机网络课程局域网详解之&#xff1a;交换机概念以太网交换机&#xff08;switch&#xff09;交换机&#xff1a;多端口间同时传输交换机转发表&#xff1a;交换表交换机&#xff1a;自学习交换机互…...

Jenkins Pipeline的hasProperty函数

函数的作用 用于判断某个参数或者字段是否存在。 用法 例子一 def projectStr "P1,P2,P3" pipeline {agent anyparameters {extendedChoice(defaultValue: "${projectStr}",description: 选择要发布的项目,multiSelectDelimiter: ,,name: SELECT_PROJ…...

芯片制造详解.净洁室的秘密.学习笔记(三)

这是芯片制造系列的第三期跟学up主三圈&#xff0c;这里对其视频内容做了一下整理和归纳&#xff0c;喜欢的可以看原视频。 芯片制造详解03&#xff1a; 洁净室的秘密&#xff5c;为何芯片厂缺人&#xff1f; 芯片制造详解.净洁室的秘密.学习笔记 三 简介一、干净的级别二、芯片…...

可解释的 AI:在transformer中可视化注意力

Visualizing Attention in Transformers | Generative AI (medium.com) 一、说明 在本文中&#xff0c;我们将探讨可视化变压器架构核心区别特征的最流行的工具之一&#xff1a;注意力机制。继续阅读以了解有关BertViz的更多信息&#xff0c;以及如何将此注意力可视化工具整合到…...

k8s Webhook 使用java springboot实现webhook 学习总结

k8s Webhook 使用java springboot实现webhook 学习总结 大纲 基础概念准入控制器&#xff08;Admission Controllers&#xff09;ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration准入检查&#xff08;AdmissionReview&#xff09;使用Springboot实现k8s-Web…...

JS逆向之猿人学爬虫第20题-wasm

文章目录 题目地址sign参数分析python算法还原往期逆向文章推荐题目地址 https://match.yuanrenxue.cn/match/20第20题被置顶到了第1页,题目难度 写的是中等 算法很简单,就一个标准的md5算法,主要是盐值不确定, 而盐值就在wasm里面,可以说难点就在于wasm分析 sign参数分…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...