顺序表的实现【数据结构】

文章目录

  • 1.线性表
  • 2.顺序表
    • 2.1 概念及结构
  • 3.模拟实现
    • 3.1 准备工作
    • 3.2 顺序表的初始化与销毁
    • 3.3 顺序表的尾插
    • 3.4 顺序表的尾删
    • 3.5顺序表的打印
    • 3.6 顺序表的头插
    • 3.7 顺序表的头删
    • 3.8 顺序表查找
    • 3.9 顺序表在pos位置插入x
    • 3.10 顺序表删除pos位置的值
  • 4.代码整合

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有线序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就是说是连续的一条线。但是在物理结构上并不一定是连续的,比如链表。
线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.顺序表

顺序表

2.1 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为静态顺序表和动态顺序表
静态顺序表
使用定长数组存储元素。

#define MAX 7
typedef int Datatype;//为了适用不同类型的顺序表
typedef struct SeqList
{Daratype a[MAX];int sz;//有效数据个数
}SL;

静态顺序表

动态顺序表
使用动态开辟的数组存储

typedef int Datatype;//为了适用不同类型的顺序表
typedef struct SeqList
{Daratype* a;int sz;//有效数据个数int capacity;//存储空间大小
}SL;

动态顺序表

3.模拟实现

静态顺序表只适合于确定知道要存储多少数据的场景下。在储存空间不确定的场景下,对于静态顺序表当MAX开大了就会造成浪费,当MAX开小了又不够。所以在实际的场景中基本都是使用动态顺序表,根据需要动态分配空间大小。
下面是模拟实现:

3.1 准备工作

定义一个结构体

typedef int Datatype;//为了适用不同类型的顺序表
typedef struct SeqList
{Datatype* a;int sz;//有效数据个数int capacity;//存储空间大小
}SL;

3.2 顺序表的初始化与销毁

对于顺序表的初始化,我的话会先给顺序表开好3个空间的大小.
注意:一定要传地址。

void InitSeqlist(SL* ps)
{ps->a = (Datatype*)malloc(sizeof(Datatype)*3);if(ps->a == NULL)//扩容失败,直接退出程序{perror("InitSeqlist");exit(-1);}ps->sz = 0;ps->capacity = 3;
}

销毁
销毁我们直接free就可以了,任何其他值赋0.

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

3.3 顺序表的尾插

插入前我们一定要先检查一下ps是不是应该空指针。
检查完ps后,对于数据的插入会存在两种情况:
1.顺序表已满,需要扩容
2.顺序表未,满直接插入
因为后面的头插与在特定位置的数据插入都会用到检查顺序是否已满,满就扩容的功能,那么我们可以封装成应该函数。

void SeqlistCapacity(SL* ps)
{if(ps->capacity == ps->sz)//满了{Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * 2*ps->capacity);if(tmp == NULL)//开辟失败{perror("realloc");exit(-1);}ps->a = tmp;ps->capacity *= 2;}
}void PushBack(SL* ps,Datatype x)
{assert(ps);//检查空间是否已满SeqlistCapacity(ps);ps->a[ps->sz] = x;ps->sz+=1;
}

3.4 顺序表的尾删

删除前我们一定要先检查一下ps是不是应该空指针。
同时还要删除该顺序表中的数据也又两种情况:
1.顺序表中的数据已经删完了,无法再删。
2.顺序表中的数据足够删除。直接删

void PopBack(SL* ps)
{assert(ps);if(ps->sz>0){ps->sz-=1;}
}

3.5顺序表的打印

直接打印就好了

void PrintSeqlist(SL* ps)
{for (int i = 0; i < ps->sz; ++i){printf("%d ", ps->a[i]);}
}

3.6 顺序表的头插

只要是插入数据就需要检查空间是否已满。
然后头插需要移动数据,我们需要把所有的数据都相后移动一位
这样的话,覆盖的顺序就很重要了,如果从前向后覆盖话,有效数据就没了
前

这样的话2就被覆盖了。
后

这样就不会了,还是不明白的话多画图就可以搞懂了。

void PushFront(SL* ps,Datatype x)
{assert(ps);SeqlistCapacity(ps);for(int i = ps->sz;i>=1;--i){ps->a[i] = ps->a[i-1];}ps->a[0] = x;ps->sz += 1;
}

3.7 顺序表的头删

只要是删除就需要判断顺序表是否为空。
这个图我就不画了,大家可以画一画从前面开始覆盖和从后面开始覆盖的图。就会豁然开朗的。

void PopFront(SL* ps)
{assert(ps);assert(ps->sz!=0);for(int i = 0;i<ps->sz-1;++i){ps->a[i] = ps->a[i+1];}ps->sz -= 1; 
}

3.8 顺序表查找

遍历顺序表,没找到的话就返回-1

int FindSeqlist(SL* ps,Datatype x)
{assert(ps);for(int i = 0;i<ps->sz;++i){if(ps->a[i] == x)return i;}return -1;//没找到
}

3.9 顺序表在pos位置插入x

就是类似与头插,头插可以理解为在0位置前插入数据。

void InsertSeqlist(SL* ps,int pos,Datatype x)
{assert(ps);assert(pos>=0&&pos<=ps->sz)SeqlistCapacity(ps);for(int i = ps->sz;i>=pos+1;--i){ps->a[i] = ps->a[i-1];}ps->a[pos] = x;	ps->sz+=1;
}

3.10 顺序表删除pos位置的值

类似于头删

void EraseSeqlist(SL* ps,int pos)
{assert(ps);assert(pos>=0&&pos<ps->sz)assert(ps->sz!=0);for(int i = pos;i<ps->sz-1;++i){ps->a[i] = ps->a[i+1];}ps->sz -= 1;
}

4.代码整合

//seqlist.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int Datatype;//为了适用不同类型的顺序表
typedef struct SeqList
{Datatype* a;int sz;//有效数据个数int capacity;//存储空间大小
}SL;void InitSeqlist(SL* ps);void DestorySeqlist(SL* ps);void SeqlistCapacity(SL* ps);void PopBack(SL* ps);void PrintSeqlist(SL* ps);void PushFront(SL* ps, Datatype x);void PopFront(SL* ps);int FindSeqlist(SL* ps, Datatype x);void InsertSeqlist(SL* ps, int pos, Datatype x);void EraseSeqlist(SL* ps, int pos);void PushBack(SL* ps, Datatype x);
//seqlist.c
#include "seqlist.h"void InitSeqlist(SL* ps)
{ps->a = (Datatype*)malloc(sizeof(Datatype) * 3);if (ps->a == NULL)//扩容失败,直接退出程序{perror("InitSeqlist");exit(-1);}ps->sz = 0;ps->capacity = 3;
}void DestorySeqlist(SL* ps)
{free(ps->a);ps->a = NULL;ps->sz = 0;ps->capacity = 0;
}void PushBack(SL* ps, Datatype x)
{assert(ps);//检查空间是否已满SeqlistCapacity(ps);ps->a[ps->sz] = x;ps->sz += 1;
}void SeqlistCapacity(SL* ps)
{if (ps->capacity == ps->sz)//满了{Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * 2*ps->capacity);if (tmp == NULL)//开辟失败{perror("realloc");exit(-1);}ps->a = tmp;ps->capacity *= 2;}
}void PopBack(SL* ps)
{assert(ps);if (ps->sz > 0){ps->sz -= 1;}
}void PrintSeqlist(SL* ps)
{for (int i = 0; i < ps->sz; ++i){printf("%d ", ps->a[i]);}printf("\n");
}void PushFront(SL* ps, Datatype x)
{assert(ps);SeqlistCapacity(ps);for (int i = ps->sz; i >= 1; --i){ps->a[i] = ps->a[i - 1];}ps->a[0] = x;ps->sz += 1;
}void PopFront(SL* ps)
{assert(ps);assert(ps->sz != 0);for (int i = 0; i < ps->sz - 1; ++i){ps->a[i] = ps->a[i + 1];}ps->sz -= 1;
}int FindSeqlist(SL* ps, Datatype x)
{assert(ps);for (int i = 0; i < ps->sz; ++i){if (ps->a[i] == x)return i;}return -1;//没找到
}void InsertSeqlist(SL* ps, int pos, Datatype x)
{assert(ps);SeqlistCapacity(ps);for (int i = ps->sz; i >= pos + 1; --i){ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->sz += 1;
}void EraseSeqlist(SL* ps, int pos)
{assert(ps);assert(ps->sz != 0);for (int i = pos; i < ps->sz - 1; ++i){ps->a[i] = ps->a[i + 1];}ps->sz -= 1;
}//test.c
#include "seqlist.h"int main()
{//测试/*SL sl;InitSeqlist(&sl);PushBack(&sl, 1);PushBack(&sl, 2);PushBack(&sl, 3);PushBack(&sl, 4);PushBack(&sl, 5);PushBack(&sl, 6);PrintSeqlist(&sl);PopBack(&sl);PopBack(&sl);PopBack(&sl);PopBack(&sl);PrintSeqlist(&sl);PopBack(&sl);PopBack(&sl);PopBack(&sl);PrintSeqlist(&sl);PushBack(&sl, 1);PushBack(&sl, 2);PushBack(&sl, 3);PushBack(&sl, 4);PushBack(&sl, 5);PushBack(&sl, 6);PushFront(&sl, 100);PushFront(&sl, 200);PrintSeqlist(&sl);InsertSeqlist(&sl, 0, 1000);PrintSeqlist(&sl);int pos = FindSeqlist(&sl, 100);PopFront(&sl);PopFront(&sl);PopFront(&sl);PopFront(&sl);PrintSeqlist(&sl);*///printf("%d", pos);return 0;
}

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

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

相关文章

【Linux学习】深入理解软硬链接

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f388;软硬链接&#x1f427;软链接&#x1f42c;硬链接 &#x1f438;总结软硬链接的原理&#x1f40d;软硬链接的应用场景&…

观成科技:海莲花活跃木马KSRAT加密通信分析

概述 自2023年8月至今&#xff0c;海莲花组织多次利用KSRAT远控木马对我国发起攻击。KSRAT通过HTTP协议与C&C服务器进行通信&#xff0c;每个样本都使用了不同的URL。其心跳包采用XOR算法进行加密&#xff0c;而控制指令包和数据回传包则使用了XOR以及“XORAES-128-CBC”组…

DC系列靶场---DC 7靶场的渗透测试

DC-7渗透测试 信息收集 地址探测 使用arpscan对目标地址进行探测 arp-scan -l I eth0 得到目标主机IP地址为172.30.1.132 扫描端口 使用nmap对目标主机做端口扫描 nmap -sS -sV -T4 -p- -O 172.30.1.132 扫描到目标主机开启了80端口、22端口。 -sS Nmap的SYN扫描&…

mapbox-gl 实现房间面生成墙(借助jsts)

文章目录 一、前言 一、前言 当我们从室外放大到室内展示室内图层时&#xff0c;我们可能只有房间面的数据&#xff0c;这时要展示房间墙数据&#xff0c;就需要借助工具对房间面进行缓冲&#xff0c;但是数据变动时&#xff0c;我们还要再次进行一下缓冲区生成操作。下面是借…

Copy as cURL 字段含义

当前端在开发过程中&#xff0c;遇到接口错误反馈给后端人员时&#xff0c;一般在此接口处右键复制为cURL。 格式如下&#xff1a; curl https://xxx.xxx.cn/xxx/xxx/management/record/list \-H accept: application/json, text/plain, */* \-H accept-language: zh-CN,zh;q0…

1.4 C 程序的编译过程与 CLion 调试技巧

目录 1 程序的编译过程 1.1 编写源代码 1.2 预处理&#xff08;Preprocessing&#xff09; 1.3 编译&#xff08;Compilation&#xff09; 1.4 汇编&#xff08;Assembly&#xff09; 1.5 链接&#xff08;Linking&#xff09; 1.6 执行 2 编译过程的输入输出文件概览 …

谷粒商城实战笔记-140-商城业务-nginx-搭建域名访问环境二(负载均衡到网关)

文章目录 一&#xff0c;通过域名访问商城架构设计1&#xff0c;为什么nginx要将请求转发给网关2&#xff0c;架构设计 二&#xff0c;配置1&#xff0c;nginx配置1.1 nginx.conf1.2 gulimall.conf1.3 配置原理 2&#xff0c;网关配置 三&#xff0c;记录2个问题1&#xff0c;网…

【C++】初识面向对象:类与对象详解

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性 本章将介绍C中一个重要的概念——类。通过类&#xff0c;我们可以类中定义成员变量和成员函数&#xff0c;实现模块化封装&#xff0c;从而构建更加抽象和复杂的工程。 &…

基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 MSER 4.2 HOG特征提取 4.3 SVM 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2017b 3.部分核心程序 &#xff08;完整版代码包含中…

CMU15445 (Fall 2023) Project 1 - Buffer Pool 思路分享

文章目录 写在前面Task 1 - LRU-K Replacement PolicyTask 2 - Disk SchedulerTask 3 - Buffer Pool ManagerNewPageFetchPageUnpinPageDeletePageFlushPage 写在最后 写在前面 操作系统为应用程序提供了默认的缓存机制&#xff0c;DBMS作为应用程序&#xff0c;为什么不使用默…

LSLM论文

解决的问题 现在的语音模型&#xff08;SLM&#xff09;增强了语音对话的能力&#xff0c;但都局限于回合制对话&#xff0c;在实时对话的情境下与用户交互的能力有所欠缺&#xff0c;例如&#xff1a;当生成的对话不满意时被打断。所以&#xff0c;这篇论文在实时的的语音语言…

ShardingSphere自定义分布式主键生成策略、自定义分片规则

文章目录 主键生成策略源码KeyGenerateAlgorithm源码入口实现扩展 自定义分布式主键生成策略 分片算法ShardingAlgorithm实现扩展 自定义分片算法踩的坑 主键生成策略源码 开发者手册 KeyGenerateAlgorithm 全限定类名org.apache.shardingsphere.sharding.spi.KeyGenerateAl…

QT界面设计开发(Visual Studio 2019)—学习记录一

一、控件升级 简要介绍&#xff1a; 简单来说&#xff0c;控件提升就是将一个基础控件&#xff08;Base Widget&#xff09;转换为一个更特定、更复杂的自定义控件&#xff08;Custom Widget&#xff09;。这样做的目的是为了在设计界面时能够使用更多高级功能&#xff0c;而不…

环境搭建:全面详尽的 MongoDB Shell MongoDB Server介绍、安装、验证与配置指南(以 Windows 系统为主)

环境搭建&#xff1a;全面详尽的 MongoDB Shell & MongoDB Server介绍、安装、验证与配置指南&#xff08;以 Windows 系统为主&#xff09; MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;以其高性能、灵活性和可扩展性而受到广泛欢迎。本文将带您完成 MongoDB 的安装…

bpmn简单使用(制作流程图)

1、先下载依赖&#xff0c;下面是我下载的版本 "bpmn-io/properties-panel": "^3.23.0", "bpmn-js": "^17.9.1", "bpmn-js-properties-panel": "^5.6.1", "camunda-bpmn-moddle": "^7.0.1",…

CTFHUB-web-RCE-eval执行

开启题目 查看源码发现直接用蚁剑连接就可以&#xff0c;连接之后发现成功了

计算机网络408考研 2020

2020 湖科大教书匠的个人空间-湖科大教书匠个人主页-哔哩哔哩视频 计算机网络408考研 历年真题解析&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili 计算机网络408考研2020年真题解析_哔哩哔哩_bilibili 1 2 3 41 11 1

乡村振兴农村煤改气建设规划设计方案

1. 方案目标与背景 《乡村振兴农村煤改气建设规划设计方案》旨在响应国家乡村振兴战略&#xff0c;通过建设规划推动农村能源结构转型&#xff0c;减少燃煤造成的环境污染&#xff0c;促进农村可持续发展。 2. 农村能源消耗现状 根据2006至2007年的全国性调研&#xff0c;农…

从一个服务预热不生效问题谈微服务无损上线

作者&#xff1a;凡问、启淮 前言 本文基于阿里云技术服务团队和产研团队&#xff0c;在解决易易互联使用 MSE&#xff08;微服务引擎&#xff09;产品无损上线功能所遇到问题的过程总结而成。本文将从问题和解决方法谈起&#xff0c;再介绍相关原理&#xff0c;后进一步拓展…

4.11.seq2seq 序列到序列学习

序列到序列学习(seq2seq) ​ 使用两个循环神经网络的编码器和解码器&#xff0c;应用于序列到薛烈类的学习任务。 ​ ​ 在图中&#xff0c;特定的"<eos>"表示序列结束词元。一旦输出序列生成此词元&#xff0c;模型就会停止预测。在循环神经网络解码器的初…