顺序表操作详解

news/2024/11/29 11:33:25/

文章目录

  • 一、线性表
  • 二、顺序表
    • 1、概念
    • 2、接口实现
      • 1>初始化顺序表
      • 2>操作结束后释放空间
      • 3>打印顺序表
      • 4>尾插
      • 5>头插
      • 6>头删
      • 7>尾删
      • 8>顺序表查找
      • 9>顺序表在pos位置插入x
      • 10>顺序表删除pos位置的值

在这里插入图片描述

一、线性表

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

二、顺序表

1、概念

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

顺序表可以分为:

  1. 静态顺序表:使用定长数组存储元素。
//顺序表静态存储
#define N 5
//这样写方便后期将int改为其他数据类型
typedef int SLDataType;typedef struct SeqList
{SLDataType arr[N];//定长数组int size;      //有效数据的个数
}SeqList;
  1. 动态顺序表:使用动态开辟的数组存储。
//顺序表动态存储
typedef int SLDataType;typedef struct SeqList
{SLDataType* a;//指向动态开辟的数组int size;    //有效数据个数int capicity;//空间的容量
}SeqList;

2、接口实现

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

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>//这样写方便后期将int改为其他数据类型
typedef int SLDateType;
//用一个结构体存放顺序表
typedef struct SeqList
{SLDateType* a;//指向动态开辟的数组int size;    //有效数据个数int capicity;//空间的容量
}SeqList;// 对数据的管理:增删查改 //初始化顺序表
void SeqListInit(SeqList* ps);
//操作结束后释放空间
void SeqListDestroy(SeqList* ps);
//打印顺序表
void SeqListPrint(SeqList* ps);//尾插
void SeqListPushBack(SeqList* ps, SLDateType x);
//头插
void SeqListPushFront(SeqList* ps, SLDateType x);
//头删
void SeqListPopFront(SeqList* ps);
//尾删
void SeqListPopBack(SeqList* ps);// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

1>初始化顺序表

void SeqListInit(SeqList* ps)
{//动态开辟内存ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 5);if (ps->a == NULL){perror("malloc failed");exit(-1);}ps->size = 0;ps->capacity = 5;
}

2>操作结束后释放空间

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

3>打印顺序表

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

4>尾插

向顺序表中插入数据时,需要先判断顺序表是否已满,如果已经满了需要进行扩容,我们将检查扩容的操作封装在一个函数中

//检查是否已满
void SeqListCheck(SeqList* ps)
{//当数据个数与容量相等时代表顺序表满了if (ps->size == ps->capacity){//因为可能会异地扩容,先用另一个指针接收//这里扩容到原来的2倍SLDateType* tmp = (SLDateType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDateType)));if (tmp == NULL){perror("realloc failed");exit(-1);}ps->a = tmp;ps->capacity *= 2;}
}

尾插只需要在顺序表的最后加上一个数据,再将size加1即可

//尾插
void SeqListPushBack(SeqList* ps, SLDateType x)
{SeqListCheck(ps);ps->a[ps->size] = x;ps->size++;
}

在这里插入图片描述

5>头插

头插需要先检查顺序表是否已满,然后将所有元素右移一位,然后将要插入的元素放到首位,这里需要从最后一个元素开始右移,不然数据会被覆盖改变

void SeqListPushFront(SeqList* ps, SLDateType x)
{SeqListCheck(ps);for (int i = ps->size - 1; i >= 0; i--){ps->a[i + 1] = ps->a[i];}ps->a[0] = x;ps->size++;
}

在这里插入图片描述

6>头删

头删直接将所有元素左移一位将首元素覆盖即可,size-1,左移需要先移动最左边元素,防止元素被覆盖

void SeqListPopFront(SeqList* ps)
{//判断顺序表是否为空assert(ps->size>0);for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

在这里插入图片描述

7>尾删

尾删只需将size-1使得访问不到即可

void SeqListPopBack(SeqList* ps)
{//判断顺序表是否为空assert(ps->size>0);ps->size--;
}

在这里插入图片描述

8>顺序表查找

在顺序表中查找x,返回其下标,找不到则返回-1

int SeqListFind(SeqList* ps, SLDateType x)
{for (int i = 0; i < ps->size - 1; i++){if (ps->a[i] == x){return i;}}return -1;
}

9>顺序表在pos位置插入x

将pos下标及以后的元素右移(需要从最后一个元素开始右移,防止覆盖),然后将x插入下标pos位置

void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{//检查下标pos是否合法assert(pos >= 0 && pos <= ps->size);SeqListCheck(ps);for (int i = ps->size - 1; i >= pos; i--){ps->a[i + 1] = ps->a[i];}ps->a[pos] = x;ps->size++;
}

在这里插入图片描述

10>顺序表删除pos位置的值

将pos下标后面的元素都左移一位(从最左边的元素开始左移,防止被覆盖),将pos下标上的元素覆盖即删除

void SeqListErase(SeqList* ps, int pos)
{//检查pos的合法性assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

在这里插入图片描述


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

相关文章

如何在Java中操作Redis(使用Jedis和Spring Data Redis来操作Redis)

在Java中操作Redis 在Java中&#xff0c;我们可以使用Jedis和Spring Data Redis来操作Redis。 一、使用Jedis操作Redis Jedis是一个流行的Java Redis客户端&#xff0c;提供了丰富的API来操作Redis。下面是使用Jedis操作Redis的步骤&#xff1a; 添加依赖 <dependency>…

PHP 基础知识全解析

PHP&#xff0c;全称 "Hypertext Preprocessor"&#xff0c;是一种流行的通用开源脚本语言&#xff0c;特别适合于 web 开发。下面是一篇深入介绍 PHP 基础知识的文章。 一、PHP 简介 PHP 是服务器端的脚本语言&#xff0c;它可以嵌入到 HTML 中去&#xff0c;用于创…

2、nacos 2.1.0注册中心原理及源码分析

一、为什么有这课程 Spring Cloud Alibaba 新版本中Seata 1.5.2和Nacos 2.1.0 在性能和使用方面都有很大提升&#xff0c;这节课将从使用和源码的角度详细讲解这两个框架。 二、设计注册中心 1、分布式框架的注意点&#xff1a;三高架构 高可用 高可用性&#xff08;High Av…

linux 查看网卡,网络情况

1&#xff0c;使用nload命令查看 #yum -y install nload 2&#xff0c; 查看eth0网卡网络情况 #nload eth0 Incoming也就是进入网卡的流量&#xff0c;Outgoing&#xff0c;也就是从这块网卡出去的流量&#xff0c;每一部分都有下面几个。 – Curr&#xff1a;当前流量 – Avg…

STM32MP157驱动开发——按键驱动(POLL 机制)

文章目录 “POLL ”机制&#xff1a;APP执行过程驱动使用的函数应用使用的函数pollfd结构体poll函数事件类型实现原理 poll方式的按键驱动程序(stm32mp157)gpio_key_drv.cbutton_test.cMakefile修改设备树文件编译测试 “POLL ”机制&#xff1a; 使用休眠-唤醒的方式等待某个…

vue+Element项目中v-for循环+表单验证

如果在Form 表单里有通过v-for动态生成&#xff0c;如何设置验证呢&#xff1f; <el-form ref"ruleFormRef" :model"ruleForm" status-icon :rules"rules" label-width"120px"class"demo-ruleForm" hide-required-aster…

js中reduce方法的常用应用场景

reduce() 方法可以用来迭代数组并且执行一个回调函数&#xff0c;将数组中的元素聚合成一个单独的值。它可以被用于一系列的操作&#xff0c;如累加求和&#xff0c;计算平均值和查找最大值或最小值等。以下是reduce() 方法的几个应用场景和相应的示例&#xff1a; 求和或求积…

Spring源码(一)Spring底层核心原理解析

Spring核心知识点 本文章将对以下Spring核心知识进行介绍。 1、Bean的生命周期底层原理 2、依赖注入底层原理 3、初始化底层原理 4、推断构造方法底层原理 5、AOP底层原理 6、Spring事务底层原理 这是入门时写的Spring代码 ClassPathXmlApplicationContext context new Cl…