揭开顺序表的神秘面纱,探索数据结构的精髓

news/2025/3/31 11:56:29/

在这里插入图片描述
❤个人主页:折枝寄北的博客
❤专栏位置:数据结构

在这里插入图片描述

数据结构-顺序表

  • 0.前言
  • 1.概念及结构
    • 1.1 基础概念
    • 1.2 顺序表结构
  • 2.实现逻辑
    • 2.1 增删查改函数声明
    • 2.2 函数逻辑实现
      • 2.2.1 初始化
      • 2.2.2 销毁
      • 2.2.3 尾插
      • 2.2.4 尾删
      • 2.2.5 头插
      • 2.2.6 头删
      • 2.2.7 扩容
      • 2.2.8 某个位置插入
      • 2.2.9 某个位置删除
      • 2.2.10 查找
  • 3.顺序表问题思考

0.前言

> 在数据结构的世界里,顺序表作为最基本的一种线性数据结构,广泛应用于各种场景。它通过连续的存储空间来存储元素,操作简单、效率高,是理解和掌握更复杂数据结构的基础。 本篇文章将带你深入了解顺序表的定义、特点以及常见操作,帮助你打下扎实的编程基础。

1.概念及结构

1.1 基础概念

概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。

  2. 动态顺序表:使用动态开辟的数组存储。

1.2 顺序表结构

静态:
在这里插入图片描述
动态:
在这里插入图片描述

2.实现逻辑

对于顺序表的实现来说,基础实现就是 “增删查改”

2.1 增删查改函数声明

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define INIT_CAPACITY 4typedef int SLDataType;
//动态顺序表---按需申请
typedef struct SeqList
{int size;    //有效数据个数int capacity;//空间容量SLDataType* a;
}SL;//增删查改
void SLInit(SL* ps);
void SLDestory(SL* ps);//尾插,尾删
void PushBack(SL* ps,SLDataType x);
void PopBack(SL* ps);//头插,头删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//显示
void SLPrint(SL* ps);//检查容量
void SLCheckcapacity(SL* ps);//某个位置插入/删除
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);//查找
int SLFind(SL* ps, SLDataType x);

以上都是顺序表逻辑所需要实现的基础函数

2.2 函数逻辑实现

2.2.1 初始化

//初始化
void SLInit(SL* ps)
{ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");return;}ps->size = 0;ps->capacity = INIT_CAPACITY;
}

2.2.2 销毁

//销毁
void SLDestory(SL* ps)
{free(ps->a);//前面申请空间aps->a = NULL;ps->capacity = ps->size = 0;
}

2.2.3 尾插

//尾插
void PushBack(SL* ps, SLDataType x)
{/*ps->a[ps->size] = x;ps->size++;*///扩容void SLCheckcapacity(ps);SLInsert(ps, ps->size, x);//ps->a[ps->size++] = x;
}

2.2.4 尾删

//尾删
void PopBack(SL* ps)
{// ps->a[ps->size - 1] = 0;//暴力检查assert(ps->size>0);//温柔检查//if (ps->size == 0)//{//	return 0;//}ps->size--;return 0;
}

2.2.5 头插

//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLInsert(ps, 0, x);//注意可能性需要扩容,防止越界//SLCheckcapacity(ps);//扩容//int end = ps->size - 1;//while (end >= 0)//{//	ps->a[end + 1] = ps->a[end];//	--end;//}}

2.2.6 头删


//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);//如果表为空,报错int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];++begin;}ps->size--;//数量减少
}

2.2.7 扩容

//扩容
void SLCheckcapacity(SL* ps)
{assert(ps);//扩容if (ps->size == ps->capacity){//原地扩容?//异地扩容? SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");return;}ps->capacity *= 2;ps->a = tmp;}}

2.2.8 某个位置插入

//某个位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckcapacity(ps);//插入int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}

2.2.9 某个位置删除

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int begin = pos + 1;while (begin < ps->size){ps->a[begin] = ps->a[begin - 1];begin++;}ps->size--;
}

2.2.10 查找

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

3.顺序表问题思考

  1. 中间/头部的插入删除,时间复杂度为O(N)

  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考:如何解决以上问题呢?
下一篇博客文章,用链表的结构解决实现。

感谢您的阅读支持!!!
后续会持续更新的!!!
文末投票支持一下!!!

在这里插入图片描述


http://www.ppmy.cn/news/1583756.html

相关文章

北理工计算机考研复试上机2014年真题

1、系统中有最近打开文件的记录&#xff0c;现用整数表示打开的文件名&#xff0c;且只 显示最近3个打开的文件&#xff0c;输出文件序列. 示例: 输入:1输出:1 输入:2输出:2, 1 输入:3 输出:3, 2, 1 输入:4 输出:4,3,2 输入:1 输出:1,4,3 输入:4 输出:1,4, 3 输入…

《Git:基本命令使用》

备份、代码还原、协同开发、追溯问题代码编写的人和时间 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理很小到很大的项目版本管理。是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。 Git工作流程图 clone&#xff08;克隆…

【学Rust写CAD】14线性插值函数(加入color.rs)

lerp 函数源码 /// 颜色线性插值/// t 取值范围 0..256&#xff0c;0 表示完全使用当前颜色(self)&#xff0c;256 表示完全使用目标颜色(end)#[inline]pub fn lerp(self, end: Color, t: u32) -> Color {let mask 0xff00ff;// 提取目标颜色的蓝色和红色分量let brb end.…

[计算机网络]网络I/O模型

欢迎来到啾啾的博客&#x1f431;。 这是一个致力于构建完善的Java程序员知识体系的博客&#x1f4da;&#xff0c;记录学习的点滴&#xff0c;分享工作的思考、实用的技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。…

Go File容器化部署方案:本地快速搭建与无公网IP远程传输文件指南

文章目录 前言1. 安装Docker2. Go File使用演示3. 安装cpolar内网穿透4. 配置Go File公网地址5. 配置Go File固定公网地址 前言 在这个信息大爆炸的时代&#xff0c;谁还没遇到过这样的尴尬场面呢&#xff1f;当你正在办公室埋头苦干时&#xff0c;手机突然跳出一条紧急邮件&a…

TCP的长连接和短连接,以及它们分别适用于什么场合

TCP长连接与短连接详解 一、核心概念对比 特性长连接&#xff08;Persistent Connection&#xff09;短连接&#xff08;Short-lived Connection&#xff09;连接生命周期一次建立后长期保持&#xff0c;多次数据交互复用同一连接每次数据交互均需新建连接&#xff0c;完成后…

内网渗透-DLL和C语言加载木马

免杀进阶技术 1、DLL的定义与使用 DLL:Dynamic Link library,动态链接库&#xff0c;是一个无法自己运行&#xff0c;需要额外的命令或程序来对其接口进行调用&#xff08;类方法、函数&#xff09;。 (1)在DevCpp中创建一个DLL项目 (2)在dllmain.c中定义源代码函数接口 #i…

CLion配置问题解决

课程笔记 https://www.yuque.com/bigdata-caoyu/newcpp CLion 激活码不可用 https://blog.csdn.net/qq_41973721/article/details/142407716 主机名&#xff1a;localhost 端口号&#xff1a;80 不为以下设置代理&#xff1a;*.github.com,plugins.jetbrains.com 插件无法下…