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

数据结构--动态顺序表

文章目录

  • 线性表
  • 动态顺序表
    • 数组与顺序表
  • 接口实现
    • 初始化:
    • 尾插:
    • 尾删
    • 头插
    • 头删
    • 指定位置插入
    • 指定位置删除
    • 查找
    • 摧毁
  • 完整代码

线性表

线性表是数据结构中最基本、最简单也是最常用的一种数据结构。线性表是指由n个具有相同数据类型的元素组成的有限序列

线性表分为顺序表和链表两种实现方式。

  1. 顺序表
    顺序表是线性表的一种实现方式,它在计算机内存中以数组的形式保存数据元素。顺序表的特点是元素在内存中是连续存储的,通过索引可以直接访问元素,因此具有较快的随机访问速度。但是顺序表的长度是固定的,需要提前申请足够的内存空间,并且插入和删除元素时需要移动其他元素,效率较低。
    在这里插入图片描述

  2. 链表
    链表是线性表的另一种实现方式,它通过指针将多个节点串联起来。每个节点包含元素和指向下一个节点的指针,所以链表的内存分布可以是离散的。链表的优点是可以动态地分配内存,插入和删除操作只需要修改指针,效率较高。但是链表的访问速度比较慢,需要遍历节点找到目标位置。
    在这里插入图片描述

本章主要介绍的是顺序表。

动态顺序表

顺序表分为静态顺序表和动态顺序表;

静态顺序表是用定长数组来进行存储元素;
在这里插入图片描述
动态顺序表是利用动态存储开辟的数组:
在这里插入图片描述

数组与顺序表

顺序表和数组在某种程度上可以说是相似的,因为顺序表的基本实现就是数组。顺序表是对数组的一种封装,它在数组的基础上提供了更加灵活的内存管理方式,使得插入、删除等操作更加高效。

接口实现

我们要将函数都包含在一个头文件中,然后用一个源文件来对函数的实现;
结构

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTypeData;typedef struct SeqList
{SLTypeData* a;int size;  //有效个数int capacity;  //空间大小}SL;

初始化:

void SLInit(SL* ps)
{assert(ps);ps->a = (SLTypeData*)malloc(sizeof(SLTypeData) * 4);if (ps->a == NULL){perror("malloc failed");exit(-1);}ps->size = 0;ps->capacity = 4;
}

对数组先开辟4个空间,然后判断是否开辟成功,成功就对size和容量进行初始化赋值;

尾插:

void AddCapacity(SL* ps)
{assert(ps);SLTypeData* cmp = (SLTypeData*)realloc(ps->a, sizeof(SLTypeData) * (ps->capacity + 3));if (cmp == NULL){perror("realloc failed");exit(-1);}ps->a = cmp;ps->capacity += 3;
}
void SLPushBack(SL* ps, SLTypeData x)
{//满需要扩容if (ps->size == ps->capacity){AddCapacity(ps);}//开始尾插ps->a[ps->size] = x;ps->size++;
}

在这里,由于还有头插和位置插入,所以就写一个函数来进行增加容量;每次容量增加3;尾插只需要在size下标进行赋值,最后再把size++即可;

我们写一个打印函数验证一下:

void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

然后在主函数中加以验证:

#include"SeqList.h"int main()
{SL test;SLInit(&test);SLPushBack(&test, 1);SLPushBack(&test, 2);SLPushBack(&test, 3);SLPushBack(&test, 4);SLPushBack(&test, 5);SLPrint(&test);return 0;
}

在这里插入图片描述

尾删

void SLPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;
}

验证:

int main()
{SL test;SLInit(&test);SLPushBack(&test, 1);SLPushBack(&test, 2);SLPushBack(&test, 3);SLPushBack(&test, 4);SLPushBack(&test, 5);SLPrint(&test);SLPopBack(&test);SLPrint(&test);return 0;
}

在这里插入图片描述

头插

void SLPushFront(SL* ps, SLTypeData x)
{assert(ps);//满扩容if (ps->size == ps->capacity){AddCapacity(ps);}//往后移for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i-1];}//头插ps->a[0] = x;ps->size++;
}

这里要插入需要对当前数组进行挪移,给第一个元素腾出空间存储;

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);return 0;
}

在这里插入图片描述

头删

void SLPopFront(SL* ps)
{assert(ps);//判断assert(ps->size > 0);//左移for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}//size减1ps->size--;}

头一个元素删完之后,需要将后面元素向前移动;最后将size–;

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);SLPopFront(&test);SLPrint(&test);return 0;
}

在这里插入图片描述

指定位置插入

//起始位置为1,例如pos=1,那么就是在下标为0的位置插入
void SLInsert(SL* ps, int pos, SLTypeData x)
{assert(ps);assert(pos > 0 && pos <= ps->size + 1); //指定pos范围//满扩容if (ps->size == ps->capacity){AddCapacity(ps);}//位置后移for (int i = ps->size; i > pos - 1; i--){ps->a[i] = ps->a[i - 1];}//插入ps->a[pos - 1] = x;ps->size++;
}

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);SLInsert(&test, 3, 88);SLPrint(&test);return 0;
}

在这里插入图片描述

指定位置删除

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos > 0 && pos <= ps->size);//指定pos范围//左移for (int i = pos - 1; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);SLInsert(&test, 3, 88);SLPrint(&test);SLErase(&test, 4);SLPrint(&test);return 0;
}

在这里插入图片描述

查找

查找对应的元素,如果有多个元素一样,返回的是最左边的元素;
返回的初始位置为1,例如下标为0,那么返回位置为1;

int SLFind(SL* ps, SLTypeData x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i+1;}}return -1;
}

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);int pos = SLFind(&test, 3);printf("3的位置是%d", pos);return 0;
}

在这里插入图片描述

摧毁

void SLDestory(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}

验证:

int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);SLDestory(&test);SLPrint(&test);return 0;
}

在这里插入图片描述

完整代码

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//动态顺序表
typedef int SLTypeData;typedef struct SeqList
{SLTypeData* a;int size;  //有效个数int capacity;  //空间大小}SL;void SLInit(SL* ps);//顺序表初始化
void SLDestory(SL* ps);//顺序表摧毁
void SLPushBack(SL* ps, SLTypeData x);//尾插
void SLPopBack(SL* ps);//尾删
void SLPushFront(SL* ps, SLTypeData x);//头插
void SLPopFront(SL* ps);//头删
int SLFind(SL* ps, SLTypeData x);//查找
void SLInsert(SL* ps, int pos, SLTypeData x);//插入
void SLErase(SL* ps, int pos);//删除
void SLPrint(SL* ps);//打印

SeqList.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"void SLInit(SL* ps)
{assert(ps);ps->a = (SLTypeData*)malloc(sizeof(SLTypeData) * 4);if (ps->a == NULL){perror("malloc failed");exit(-1);}ps->size = 0;ps->capacity = 4;
}void SLDestory(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//满扩容
void AddCapacity(SL* ps)
{assert(ps);SLTypeData* cmp = (SLTypeData*)realloc(ps->a, sizeof(SLTypeData) * (ps->capacity + 3));if (cmp == NULL){perror("realloc failed");exit(-1);}ps->a = cmp;ps->capacity += 3;
}
void SLPushBack(SL* ps, SLTypeData x)
{//满需要扩容if (ps->size == ps->capacity){AddCapacity(ps);}//开始尾插ps->a[ps->size] = x;ps->size++;
}void SLPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;
}void SLPushFront(SL* ps, SLTypeData x)
{assert(ps);//满扩容if (ps->size == ps->capacity){AddCapacity(ps);}//往后移for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i-1];}//头插ps->a[0] = x;ps->size++;
}void SLPopFront(SL* ps)
{assert(ps);//判断assert(ps->size > 0);//左移for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}//size减1ps->size--;}int SLFind(SL* ps, SLTypeData x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i+1;}}return -1;
}void SLInsert(SL* ps, int pos, SLTypeData x)
{assert(ps);assert(pos > 0 && pos <= ps->size + 1);//满扩容if (ps->size == ps->capacity){AddCapacity(ps);}//位置后移for (int i = ps->size; i > pos - 1; i--){ps->a[i] = ps->a[i - 1];}//插入ps->a[pos - 1] = x;ps->size++;
}void SLErase(SL* ps, int pos)
{assert(ps);assert(pos > 0 && pos <= ps->size);assert(pos > 0);//左移for (int i = pos - 1; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");}

test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"int main()
{SL test;SLInit(&test);SLPushFront(&test, 1);SLPushFront(&test, 2);SLPushFront(&test, 3);SLPushFront(&test, 4);SLPushFront(&test, 5);SLPrint(&test);SLDestory(&test);SLPrint(&test);return 0;
}

相关文章:

数据结构--动态顺序表

文章目录 线性表动态顺序表数组与顺序表 接口实现初始化&#xff1a;尾插&#xff1a;尾删头插头删指定位置插入指定位置删除查找摧毁 完整代码 线性表 线性表是数据结构中最基本、最简单也是最常用的一种数据结构。线性表是指由n个具有相同数据类型的元素组成的有限序列。 线…...

笔试数据结构选填题

目录 卡特兰数Catalan&#xff1a;出栈序列/二叉树数 树 二叉树 N01N2 哈夫曼树&#xff08;最优二叉树&#xff09;Huffman 度m的哈夫曼树只有度为0和m的结点&#xff1a;Nm(n-1)/(m-1) 平衡二叉树AVL Nh表示深度为h最少结点数&#xff0c;则N00&#xff0c;N11&#…...

# 鸢尾花的案例学习

# 鸢尾花的案例学习 # 1. 导入小型的数据 from sklearn.datasets import load_iris import numpy as np import pandas as pd import seaborn as sbn import matplotlib.pyplot as plt # 2. 获取数据 irisload_iris() # 3.查看数据print("数据集\n ",len(iris.d…...

线程、进程的区别

线程、进程的区别 在开发中&#xff0c;我们经常听到线程和进程两个概念&#xff0c;它们都是操作系统的基本概念&#xff0c;操作系统以进程为基本单位分配存储器&#xff0c;以线程为基本单位分配CPU。虽然它们有很多相似之处&#xff0c;但是它们也有很大的区别。本文将详细…...

在 Ubuntu 上安装 Docker 桌面

Ubuntu 22.04 (LTS) 安装 Docker 桌面 要成功安装 Docker Desktop&#xff0c;您必须&#xff1a; 满足系统要求拥有 64 位版本的 Ubuntu Jammy Jellyfish 22.04 (LTS) 或 Ubuntu Impish Indri 21.10。对于非 Gnome 桌面环境&#xff0c;必须安装 gnome-terminal&#xff1a;…...

【WebRTC---序篇】(七)RTC多人连麦方案

服务端可以选择mediasoup&#xff0c;作为SFU服务器&#xff0c;只负责转发数据 下图举例三个Client (browser或者客户端)同时加入一个房间&#xff0c;每个app同时发布一路视频和一路音频&#xff0c;并且接受来自其他app的音视频流&#xff0c;mediasoup内部的结构如下&…...

【Java可执行命令】(十六)诊断命令请求发送工具 jcmd:提供一种简单而强大的方式来管理和监控 Java 进程 ~

Java可执行命令之jcmd 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式3.2 jcmd -l&#xff1a;列出正在运行的 Java 进程3.3 jcmd < pid> help&#xff1a;列出特定进程的诊断命令列表3.4 jcmd < pid> < command>&#xff1a;执行诊断命令 4️⃣ 应用场景…...

如何创建无序列表和有序列表?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 无序列表⭐ 无序列表⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴…...

【MongoDB】初识、安装MongoDB

目录 一、MongoDB主要应用场景 二、MongoDB简介 三、MongoDB相关特点 四、MongoDB的安装 一、MongoDB主要应用场景 传统的数据库如MySQL在应对三高场景时显得力不从心 三高&#xff1a; High performance 对数据库高并发读写的需求 High Storage 对海量数据的高效率存储和 …...

方法区内存溢出及常量池

22 方法区-定义 是所有线程共享的一块区域。 存储了和类结构相关信息。运行时常量池&#xff0c; 方法区在虚拟机启动时被创建&#xff0c;逻辑上是堆的组成部分。方法区内存不足&#xff0c;也会导致oom异常。 是一个概念上的东西&#xff0c; 1.6使用永久代作为方法区&#…...

【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p_invitation.c文件的介绍

本文主要介绍external/wpa_supplicant_8/src/p2p/p2p_invitation.c文件 这里主要介绍6个方法 1.p2p_invite //p2p邀请调用此方法 2.p2p_invite_send //对p2p_invite方法进行补充 3. p2p_process_invitation_resp 4.p2p_process_invitation_req 5.p2p_build_invitation_re…...

智能仪表板DevExpress Dashboard v23.1亮点 - 增强对自定义导出的支持

DevExpress Dashboard v23.1版本增强了自定义导出到Excel的功能等&#xff0c;欢迎下载最新版本体验&#xff01; DevExpress Dashboard v23.1正式版下载(Q技术交流&#xff1a;523159565&#xff09; 所有平台 导出自定义仪表板项目到Excel 用户现在可以在WinForms和Web应…...

分布式应用:ELK企业级日志分析系统

目录 一、理论 1.ELK 2.ELK场景 3.完整日志系统基本特征 4.ELK 的工作原理 5.ELK集群准备 6.Elasticsearch部署&#xff08;在Node1、Node2节点上操作&#xff09; 7.Logstash 部署&#xff08;在 Apache 节点上操作&#xff09; 8.Kiabana 部署&#xff08;在 Node1 节点…...

Mac与windows传文件(超过4G且速度超快,非共享)

MAC与Windows文件互传 背景 尝试了网上的一些方法&#xff0c;诸如设置共享文件夹方法等&#xff0c;但是实际使用中感觉效果一般&#xff0c;对于一些小的文件共同编辑速度还可以。但是在备份或者传递一些较大文件或者很多细小文件的时候就有点捉襟见肘了。制作了一个MAC可读…...

2023年第四届“华数杯”数学建模思路 - 案例:退火算法

## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 退火算法原理 1.1 物理背景 在热力学上&#xff0c;退火&#xff08;annealing&#xff09;现象指物体逐渐降温的物理现象&#xff0c;温度愈低&#…...

STM32 UDS Bootloader开发-上位机篇-CANoe制作(3)

文章目录 前言刷写脚本34服务写入数据的实现定时函数writeBlockData函数Checksum总结前言 上一篇文章中介绍了CAPL刷写脚本的大部分内容,本文继续介绍34,36,37服务的实现,及checksum中遇到的坑 刷写脚本 34服务 void requestDownLoad(struct Block hexfile) {gTxBuffer[…...

GO语言的垃圾回收机制

内存垃圾的产生 程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C等早期编程语言栈上的内存回由编译器负责管理回收&#xff0c;而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收&#xff0c;而堆上的内存由编译器…...

vim粘贴内容格式混乱解决方法

问题 复制本地文件内容后&#xff0c;咱贴到vim文本内&#xff0c;格式错乱 解决方法 打开vim配置文件 最后面加入一行 vim /etc/vimrc set pastetoggle<F11> 开发vim文件&#xff0c;进入后先按F11进入交互模式 shift insert 再次粘贴 解决...

基于Orangepi 3 lts 的云台相机

利用orangepi 3 lts 和arduino nano 制作了一个云台相机&#xff0c;可用于室内监控。 硬件&#xff1a; orangepi 3 ,arduino nano ,usb相机&#xff0c;180度舵机两个 WeChat_20230806213004 软件&#xff1a; 整体采用mqtt进行消息的中转。 相机采用python 利用opencv…...

Go重写Redis中间件 - Go实现Redis持久化

GO实现Redis持久化 项目开发到这里,我们的下一步就是实现Redis的持久化落盘功能,Redis是一个内存型的数据库,在之前我们实现的单机版Redis如果把进程杀掉,我们通过GET、SET指令存储的数据都将不复存在,数据只存在内存的map里面,重启之后什么都没有了 我们现在的目标就是…...

S32K3 Autosar开发环境一站式部署指南

1. S32K3 Autosar开发环境概述 第一次接触S32K3 Autosar开发的朋友可能会被复杂的工具链吓到。其实只要理清思路&#xff0c;整个环境搭建就像组装乐高积木——每个组件都有明确的位置和功能。S32K3是NXP面向汽车电子的明星MCU&#xff0c;而Autosar则是汽车软件开发的行业标准…...

代码锁:极简主义下的单例模式与模块化设计实践

1. 项目概述&#xff1a;一个极简主义者的代码锁最近在GitHub上看到一个挺有意思的项目&#xff0c;叫cdotlock/the_only。光看这个名字&#xff0c;你可能有点摸不着头脑&#xff0c;cdotlock是什么&#xff1f;the_only又是什么意思&#xff1f;这其实是一个典型的极简主义开…...

夸克禁闭的自指拓扑严格证明:自指威尔逊环不变量与线性禁闭势

夸克禁闭的自指拓扑严格证明&#xff1a;自指威尔逊环不变量与线性禁闭势 世毫九实验室 | 认知量子引力研究中心 作者&#xff1a;方见华 日期&#xff1a;2026年5月18日 密级&#xff1a;公开 | 编号&#xff1a;TR-016-QC 摘要 本文基于世毫九自指规范场框架&#xff0c;构…...

Linux高手必备:从安全操作到高效运维的12个核心习惯

1. 为什么说“习惯”是Linux高手的护城河刚接触Linux那会儿&#xff0c;我总觉得高手和菜鸟的区别在于记住了多少命令、会不会写复杂的脚本。后来踩了无数坑、熬了无数夜、甚至搞崩过几次生产环境后&#xff0c;我才恍然大悟&#xff1a;真正的分水岭&#xff0c;其实藏在那些日…...

Flutter 测试完全指南

Flutter 测试完全指南 引言 测试是软件质量保障的关键环节。本文将深入探讨 Flutter 测试的各种类型和最佳实践。 基础概念回顾 测试类型 单元测试: 测试单个函数或方法Widget 测试: 测试单个 Widget集成测试: 测试多个组件的交互性能测试: 测试应用性能 测试工具 test:…...

AI量化交易框架解析:从架构设计到实战部署

1. 项目概述&#xff1a;一个AI驱动的加密资产对冲基金框架最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“ai-hedge-fund-crypto”。光看名字&#xff0c;就能感受到一股浓浓的“量化AI加密”的混合气息。这其实是一个开源框架&#xff0c;旨在帮助开发者或量化研究员&…...

5分钟免费制作专业AI翻唱:AICoverGen完整指南

5分钟免费制作专业AI翻唱&#xff1a;AICoverGen完整指南 【免费下载链接】AICoverGen A WebUI to create song covers with any RVC v2 trained AI voice from YouTube videos or audio files. 项目地址: https://gitcode.com/gh_mirrors/ai/AICoverGen 想让AI帮你翻唱…...

恶劣环境下LED发光服饰的可靠系统构建:从设计到工艺的工程实践

1. 项目概述与核心挑战如果你曾经尝试过制作一件会发光的服装&#xff0c;无论是为了音乐节、万圣节还是水下表演&#xff0c;你大概都体会过那种“亮一次&#xff0c;修三次”的挫败感。LED灯带在工作室的桌面上测试时完美无瑕&#xff0c;一旦穿到身上&#xff0c;开始活动、…...

终极指南:使用Python开源工具破解百度网盘限速,实现高速免费下载

终极指南&#xff1a;使用Python开源工具破解百度网盘限速&#xff0c;实现高速免费下载 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘几十KB的下载速度而烦恼…...

从TPM到机密计算:远程证明技术原理与zap1项目实践指南

1. 项目概述与核心价值最近在整理一些零散的学习笔记时&#xff0c;发现了一个挺有意思的项目&#xff0c;叫Frontier-Compute/zap1-learning-attestation。乍一看这个标题&#xff0c;可能有点让人摸不着头脑&#xff0c;尤其是对于刚接触可信计算或者硬件安全领域的朋友来说。…...