顺序表基本操作全面解析

文章目录

  • 1.线性表
  • 2.顺序表分类
    • 2.1 静态顺序表
    • 2.2 动态顺序表
  • 3. 顺序表各接口实现
    • 1. 定义结构体`(Seqlist)`
    • 2. 结构体初始化`(SLInit)`
    • 3.检查容量 `(SLCheckCapacity)`
    • 4.打印数据 `(SLPrintf)`
    • 5.插入操作
      • 5.1 从数据头部插入`(SLPushFront)`
      • 5.2 从数据尾部插入`(SLPushBack)`
      • 5.3 从任意下标位置的插入`(SLInsert)`
    • 6.删除操作
      • 6.1 从数据头部删除`(SLPopFront)`
      • 6.2 从数据尾部删除`(SLPopBack)`
      • 6.3 从任意下标位置的删除`(SLErase)`
    • 7 销毁操作 `(SLDestroy)`
  • 4.完整代码
    • 4.1 SeqList.h文件
    • 4.2 SeqList.c文件
    • 4.3 Test.c文件

1.线性表

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

案例:蔬菜分为绿叶类、瓜类、菌菇类。线性表指的是具有部分相同特性的一类数据结构的集合

2.顺序表分类

顺序表和数组的区别:
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口

2.1 静态顺序表

静态顺序表概念:使用定长数组存储元素
缺点是定义空间小了不够用,定义大了浪费,不好把控。

在这里插入图片描述

2.2 动态顺序表

动态顺序表概念:使用动态开辟的数组存储。
动态顺序表 根据自己的需求调整大小,
在这里插入图片描述

3. 顺序表各接口实现

首先建立3个文件
1.SeqList.h头文件,用来声明函数
2.SeqList.c文件,用来定义函数
3.Test.c文件,用来测试函数

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

1. 定义结构体(Seqlist)

在SeqList.h头文件中

typedef int SLDataType;typedef struct Seqlist
{SLDataType* a;int size;       // 有效数据int capacity;   // 空间容量
}SL;

2. 结构体初始化(SLInit)

注意下述代码皆是:
SeqList.h头文件中定义函数
SeqList.c文件中实现函数
Test.c文件中测试函数

SeqList.h文件中
定义函数:
在这里插入图片描述
SeqList.c文件中
实现函数:

 void SLInit(SL *ps)     // 数据表初始化
{assert(ps);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}

Test.c文件中
测试函数:

int main()
{SL s1;SLInit(&s1);return 0;
}

调试结果:
在这里插入图片描述

3.检查容量 (SLCheckCapacity)

定义函数:
在这里插入图片描述
实现函数:

void SLCheckCapacity(SL* ps)  // 检查内存是否足够,不够就扩容。
{//一般情况为了避免频繁插入数据而增容,或者一下开辟很大的空间,我们一般是每次增容2倍assert(ps);if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;}
}

测试函数:

int main()
{SL s1;SLInit(&s1);SLCheckCapacity(&s1);return 0;
}

调试结果:
在这里插入图片描述

4.打印数据 (SLPrintf)

定义函数:
在这里插入图片描述
实现函数:

void SLPrintf(SL* ps)   // 数据表打印
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

5.插入操作

5.1 从数据头部插入(SLPushFront)

定义函数:
在这里插入图片描述
实现函数:

void SLPushFront(SL* ps, SLDataType x)  // 头插
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

5.2 从数据尾部插入(SLPushBack)

定义函数:
在这里插入图片描述
实现函数:

void SLPushBack(SL* ps, SLDataType x)   // 尾插
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

5.3 从任意下标位置的插入(SLInsert)

定义函数:
在这里插入图片描述

实现函数:

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++;
}

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

6.删除操作

6.1 从数据头部删除(SLPopFront)

定义函数:
在这里插入图片描述

实现函数:

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--;
}

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

6.2 从数据尾部删除(SLPopBack)

定义函数:
在这里插入图片描述
实现函数:

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

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

6.3 从任意下标位置的删除(SLErase)

定义函数:
在这里插入图片描述

实现函数:

void SLErase(SL* ps, int pos)    // 任意下标位置的删除
{assert(ps);assert(pos >= 0 && pos < ps->size);   // 这里删除不能用等于ps->size,ps->size看作下标的话相当于下标的最后一个位置+1int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}

动图解析:
在这里插入图片描述

测试函数结果:
在这里插入图片描述

7 销毁操作 (SLDestroy)

定义函数:
在这里插入图片描述

实现函数:

void SLDestroy(SL* ps)  // 数据表销毁
{assert(ps);if (ps->a != NULL){free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;}
}

在这里插入图片描述

4.完整代码

4.1 SeqList.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;typedef struct Seqlist
{SLDataType* a;int size;       // 有效数据int capacity;   // 空间容量
}SL;void SLInit(SL *ps);    // 数据表初始化
void SLDestroy(SL *ps); // 数据表销毁void SLPushFront(SL* ps, SLDataType x); // 头插
void SLPushBack(SL *ps ,SLDataType x);  // 尾插void SLPopFront(SL* ps);  // 头删
void SLPopBack(SL* ps);   // 尾删void SLCheckCapacity(SL* ps); // 检查内存是否足够,不够就扩容。
void SLPrintf(SL* ps);  // 数据表打印void SLInsert(SL* ps, int pos, SLDataType x);  //任意下标位置的插入
void SLErase(SL* ps, int pos);  //任意下标位置的删除

4.2 SeqList.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void SLCheckCapacity(SL* ps)  // 检查内存是否足够,不够就扩容。
{assert(ps);if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;}
}void SLPrintf(SL* ps)   // 数据表打印
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SLInit(SL *ps)     // 数据表初始化
{assert(ps);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}void SLDestroy(SL* ps)  // 数据表销毁
{assert(ps);if (ps->a != NULL){free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;}
}void SLPushFront(SL* ps, SLDataType x)  // 头插
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}void SLPushBack(SL* ps, SLDataType x)   // 尾插
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}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--;
}void SLPopBack(SL* ps)  // 尾删
{assert(ps);assert(ps->size>0);ps->size--;
}// pos是下标
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++;
}void SLErase(SL* ps, int pos)    // 任意下标位置的删除
{assert(ps);assert(pos >= 0 && pos < ps->size);   // 这里删除不能用等于ps->size,ps->size看作下标的话相当于下标的最后一个位置+1int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}

4.3 Test.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void TestSL1()  // 头插,尾插
{printf("TestSL1:\n");SL s1;SLInit(&s1);SLPushFront(&s1, 10);SLPushBack(&s1, 30);SLPrintf(&s1);  
}void TestSL2()  // 头删,尾删
{printf("TestSL2:\n");SL s1;SLInit(&s1);SLPushFront(&s1, 10);SLPushBack(&s1, 30);SLPushFront(&s1, 10);SLPushBack(&s1, 30);SLPrintf(&s1);SLPopBack(&s1);SLPopFront(&s1);SLPrintf(&s1);
}void TestSL3()//任意下标位置的插入,删除测试
{printf("TestSL3:\n");SL s1;SLInit(&s1);SLPushFront(&s1, 10);SLPushBack(&s1, 30);SLPrintf(&s1);SLInsert(&s1, 1, 520);SLPrintf(&s1);SLErase(&s1, 2);SLPrintf(&s1);
}int main()
{TestSL1();TestSL2();TestSL3();
}

运行结果如下:
在这里插入图片描述

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

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

相关文章

Matplotlib颜色条的配置_Python数据分析与可视化

Matplotlib颜色条配置 基本颜色颜色条选择配色方案颜色条刻度的限制与扩展功能的设置离散型颜色条 基本颜色 Matplotlib提供了8种指定颜色的方法&#xff1a; 在[0&#xff0c;1]中的浮点值的RGB或RGBA元组&#xff08;例如 (0.1, 0.2, 0.5) 或&#xff08;0.1&#xff0c; 0.…

实验4.数据全量、增量、比较更新

【实验目的】 1.利用Kettle的“表输入”&#xff0c;“表输入出”&#xff0c;”JavaScript代码”组件&#xff0c;实现数据全量更新。 2.熟练掌握“JavaScript代码”&#xff0c;“表输入”&#xff0c;“表输入出”组件的使用&#xff0c;实现数据全量更新。 【实验原理】 …

Uptime Kuma 企业微信群机器人告警

curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa \-H Content-Type: application/json \-d {"msgtype": "text","text": {"content": "hello world"}}企业微信群机器人ke…

【数据结构初阶】栈和队列

栈和队列 1.栈1.1栈的概念和结构1.2栈的实现 2.队列2.1队列的概念和结构2.2队列的实现 1.栈 1.1栈的概念和结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。…

12英寸双轴半自动划片机:颠覆传统划切工艺的五大优势

随着科技的飞速发展&#xff0c;半导体行业对精密划切设备的需求日益增长。在这篇文章中&#xff0c;我们将深入探讨12英寸双轴半自动划片机的优势&#xff0c;这种划片机在半导体制造过程中扮演着至关重要的角色。以下是这种划片机的五大优势。 一、高精度划切 12英寸双轴半自…

使用websocket获取thingsboard设备的实时数据

背景 有一个读者前来咨询,如何实时获取设备的遥测数据。 其实tb是有提供websocket接口来获取设备数据的。而且还支持js跨域调用。下面给大家演示一下。 websocket地址 完整代码 <!DOCTYPE HTML> <html><h

8年老鸟整理,自动化测试-准备测试数据详细...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 大部分类型的测试…

竞赛python区块链实现 - proof of work工作量证明共识算法

文章目录 0 前言1 区块链基础1.1 比特币内部结构1.2 实现的区块链数据结构1.3 注意点1.4 区块链的核心-工作量证明算法1.4.1 拜占庭将军问题1.4.2 解决办法1.4.3 代码实现 2 快速实现一个区块链2.1 什么是区块链2.2 一个完整的快包含什么2.3 什么是挖矿2.4 工作量证明算法&…

Rust错误处理:Result

文章目录 简介错误匹配 Rust基础教程&#xff1a; 初步⚙ 所有权⚙ 结构体和枚举类⚙ 函数进阶⚙ 泛型和特征⚙ 并发和线程通信⚙ cargo包管理⚙ 可空类型Option Rust进阶教程&#xff1a; 用宏实现参数可变的函数⚙ 类函数宏 简介 Rust中没有提供类似try…catch之类…

Leetcode——121 买卖股票的最佳时机

(超时。。。。。。&#xff09;除了暴力法我是真的。。。。。。 class Solution {public int maxProfit(int[] prices) {int len prices.length;int max0;for(int i0;i<len-1;i){for(int ji1;j<len;j){int income prices[j] - prices[i];if(income>max){maxincome;…

2023亚太杯数学建模赛题人工精准翻译

大家好&#xff0c;亚太杯今天早上6点已经开赛啦&#xff0c;然后我在这里给大家带来赛题的精准人工翻译&#xff0c;防止大家直接用软件翻译导致某些地方乱码或者翻译不精准&#xff0c;这会导致后续做题过程出现很大偏差。 注意&#xff0c;以下翻译均免费发放word形式的哈&…

VUE+element可以为空不为空时只能为(正整数和0)的验证

rule{ 变量: [ { required: true, validator: validateparamPosition, trigger: blur }] } ​​​​​​​ ​​​​​​​ ​​​​​​​ var validateparamPosition (rule, value, callback) > { if (!value) { //先判断空可以过 ca…