当前位置: 首页 > 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里面,重启之后什么都没有了 我们现在的目标就是…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

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

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

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...