顺序表基本操作

2023-11-01


1. 顺序表插入元素

向顺序表中插入数据元素,根据插入位置的不同,可分为以下 3 种情况:

  • 插入到顺序表的表头;
  • 在表的中间位置插入元素;
  • 尾随顺序表中已有元素,作为顺序表中的最后一个元素;

虽然数据元素插入顺序表中的位置有所不同,但是都使用的是同一种方式去解决,即:通过遍历,找到数据元素要插入的位置,然后做如下两步工作:

  • 将要插入位置元素以及后续的元素整体向后移动一个位置;
  • 将元素放到腾出来的位置上;

例如,在 {1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:

  1. 找到目标元素位置:遍历至顺序表存储第 3 个数据元素的位置
    在这里插入图片描述
  2. 移动元素,将插入位置腾出:将元素 3 以及后续元素 4 和 5 整体向后移动一个位置
    在这里插入图片描述
  3. 将新元素 6 插入到腾出的位置
    在这里插入图片描述

因此,顺序表插入数据元素的 C 语言实现代码如下:

//插入函数,其中elem为插入的元素,position为插入到顺序表的位置
SqList ListInsert(SqList L, int elem, int position)
{
    //判断插入本身是否存在问题(如果插入元素位置比整张表的长度+1还大(如果相等,是尾随的情况),或者插入的位置本身不存在,程序作为提示并自动退出)
    if((position > L.length + 1) || (position < 1))
    {
        printf("插入位置有问题");
        return L;
    }
    //做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
    if(L.length == L.size)
    {
        L.head = (int *)realloc(L.head, (L.size + 1) * sizeof(int));
        if(L.head == NULL)
        {
            printf("存储分配失败\n");
            return L;
        }
        L.size++;
    }
    //插入操作,需要将从插入位置开始的后续元素,逐个后移
    for(int i = L.length - 1; i >= position - 1; i--)
    {
        L.head[i+1] = L.head[i];
    }
    //后移完成后,直接将所需插入元素,添加到顺序表的相应位置
    L.head[position - 1] = elem;
    //由于添加了元素,所以长度+1
    L.length++;
    return L;
}

2. 顺序表删除元素

从顺序表中删除指定元素,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。

后续元素整体前移一个位置,会直接将目标元素的值覆盖,可间接实现删除元素的目的

例如,从 {1,2,3,4,5} 中删除元素 3 的过程如图所示:
在这里插入图片描述

因此,顺序表删除元素的 C 语言实现代码为:

 SqList ListDelete(SqList L, int position)
{
    if((position > L.length) || (position < 1))
    {
        printf("被删除元素的位置有误\n");
        return L;
    }
    for(int i = position; i < L.length; i++)
    {
        L.head[i-1] = L.head[i];
    }
    L.length--;
    return L;
}

3. 顺序表查找元素

顺序表中查找目标元素就是遍历顺序表看是否存在元素和目标元素相等。C语言实现代码为:

//查找函数,其中,elem表示要查找的数据元素的值
int LocateElem(SqList L, int elem)
{
    for(int i = 0; i < L.length; i++)
    {
        if(L.head[i] == elem)
        {
            return i + 1;
        }
    }
    //如果查找失败,返回-1
    return -1;
}

4. 顺序表更改元素

顺序表更改元素的实现过程是:

  1. 找到目标元素;
  2. 直接修改该元素的值;
//更改函数,其中,elem为要更改的元素,newElem为新的数据元素
SqList ListModify(SqList L, int OldElem, int NewElem)
{
    int position = LocateElem(L, OldElem);
    L.head[position - 1] = NewElem;//由于返回的是元素在顺序表中的位置,所以-1就是该元素在数组中的下标
    return L;
}

以上是顺序表使用过程中最常用的基本操作,如下是C语言完整代码清单

#include<stdio.h>
#include<stdlib.h>

#define SIZE 5  //对SIZE进行宏定义,表示顺序表申请空间的大小
typedef struct List
{
    int *head;  //声明了一个名为head的长度不确定的数组,也叫“动态数组”
    int length; //记录当前顺序表的长度
    int size;   //记录顺序表分配的存储容量
}SqList;

SqList InitList();
SqList ListInsert(SqList L, int elem, int position);
SqList ListDelete(SqList L, int position);
int LocateElem(SqList L, int elem);
SqList ListModify(SqList L, int OldElem, int NewElem);
void DisplayList(SqList L);

int main()
{
    SqList L = InitList();
    for (int i=0; i < SIZE; i++) 
    {
        L.head[i] = (i + 1);
        L.length++;
    }
    printf("原顺序表:\n");
    DisplayList(L);
  
    printf("删除元素1:\n");
    L = ListDelete(L, 1);
    DisplayList(L);
  
    printf("在第2的位置插入元素5:\n");
    L = ListInsert(L, 5, 2);
    DisplayList(L);
  
    printf("查找元素3的位置:\n");
    int position = LocateElem(L, 3);
    printf("%d\n", position);
  
    printf("将元素3改为6:\n");
    L = ListModify(L, 3, 6);
    DisplayList(L);
    return 0;
}

SqList InitList()
{
    SqList L;

    L.head = (int*)malloc(SIZE * sizeof(int));  //构造一个空的顺序表,动态申请存储空间
    
    if(!(L.head))   //如果申请失败,作出提示并直接退出程序
    {
        printf("初始化失败");
        exit(0);
    }

    L.size = SIZE; //空表的初始存储空间为SIZE
    L.length = 0;   //空表的长度初始化为0

    return L;
}

//插入函数,其中,elem为插入的元素,position为插入到顺序表的位置
SqList ListInsert(SqList L, int elem, int position)
{
    //判断插入本身是否存在问题(如果插入元素位置比整张表的长度+1还大(如果相等,是尾随的情况),或者插入的位置本身不存在,程序作为提示并自动退出)
    if((position > L.length + 1) || (position < 1))
    {
        printf("插入位置有问题");
        return L;
    }
    //做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
    if(L.length == L.size)
    {
        L.head = (int*)realloc(L.head, (L.size + 1) * sizeof(int));
        if(L.head == NULL)
        {
            printf("存储分配失败\n");
            return L;
        }
        L.size++;
    }
    //插入操作,需要将从插入位置开始的后续元素,逐个后移
    for(int i = L.length - 1; i >= position - 1; i--)
    {
        L.head[i+1] = L.head[i];
    }
    //后移完成后,直接将所需插入元素,添加到顺序表的相应位置
    L.head[position - 1] = elem;
    //由于添加了元素,所以长度+1
    L.length++;
    return L;
}

SqList ListDelete(SqList L, int position)
{
    if((position > L.length) || (position < 1))
    {
        printf("被删除元素的位置有误\n");
        return L;
    }
    for(int i = position; i < L.length; i++)
    {
        L.head[i-1] = L.head[i];
    }
    L.length--;
    return L;
}

//查找函数,其中,elem表示要查找的数据元素的值
int LocateElem(SqList L, int elem)
{
    for(int i = 0; i < L.length; i++)
    {
        if(L.head[i] == elem)
        {
            return i + 1;
        }
    }
    //如果查找失败,返回-1
    return -1;
}

//更改函数,其中,elem为要更改的元素,newElem为新的数据元素
SqList ListModify(SqList L, int OldElem, int NewElem)
{
    int position = LocateElem(L, OldElem);
    L.head[position - 1] = NewElem;//由于返回的是元素在顺序表中的位置,所以-1就是该元素在数组中的下标
    return L;
}

//输出顺序表中元素的函数
void DisplayList(SqList L)
{
    for(int i = 0; i < L.length; i++)
    {
        printf("%d ", L.head[i]);
    }
    printf("\n");
}

程序运行结果为:

原顺序表:
1 2 3 4 5
删除元素1:
2 3 4 5
在第2的位置插入元素5:
2 5 3 4 5
查找元素3的位置:
3
将元素3改为6:
2 5 6 4 5

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

顺序表基本操作 的相关文章

  • 如何做代码评审(code review)

    1 定义 Code Review 即日常所说的代码评审或代码回顾 主要是在软件开发的过程中 对功能源代码进行评审 其目的是找出并修正软件开发过程中出现的错误的过程 提高和改进代码质量的过程 2 目的 2 1 提前发现缺陷 code revi
  • 电阻的固有噪声(热噪声)

    电阻的固有噪声是指其自身产生的噪声 包括热噪声和过剩噪声 热噪声亦称白噪声 是由导体中电子的热震动引起的 它存在于所有电子器件和传输介质中 它是温度变化的结果 但不受频率变化的影响 热噪声是在所有频谱中以相同的形态分布 它是不能够消除的 由
  • css怎么跟html搞一起,css和html的四种结合方式

    1 在每个HTML标签上面都有一个属性 style 把css和HTML结合在一起 我是一只小小鸟 2 使用HTML的一个标签实现 css代码 div background color red color gray 3 在style标签里面
  • Java实现多线程下载文件

    这是本人在实际开发当中遇到的多线程下载文件并记录下来 public class DownloadUtil private String pathFile private String strFile private DownloadThre
  • 关于java中的泛型 T 和 ?的区别(转载+改动)

    T表示泛型 new的时候要加入泛型 更方便通用 表示不确定的类型 一般用在通配 Object表示java中所有类的父类 在集合中使用时要格外注意 jdk为了便于理解 用K表示键 V表示值 T表示type类型 E表示enum枚举 其实这四个都
  • 飞链云元宇宙、区块链、3D数字艺术品、AI绘画共创数字新生态

    2022 飞链云生态 飞链云元宇宙 区块链 3D数字艺术品 AI绘画共创数字新生态 本文地址 https feilianyun yuque com books share c2d90a1b 6bba 4d23 9fb8 65a011cf3a
  • SpringBoot解析json文件

    SpringBoot解析json文件 第一步 要有一个自定义的json文件 例如 文件名 user json username 张三 userage 20 username 莉莉 userage 18 第二步 要有一个实体类 例如 Data
  • linux vscode 基于 configurationProvider 设置提供的信息检测到 #include 错误

    代码正常 vscode经常性会出现include报错 大多数并不是includepath设置错误的原因 困扰了我好几天 结合大家的提示终于解决了问题 现在把方法分享给大家 希望对大家有帮助 解决办法 1 在命令行执行 gcc v E x c
  • Django 创建第一个web项目

    版本说明 python 3 7 0 django 3 0 6 Django 管理工具 django admin 部署虚拟环境 安装virtualenv pip install virtualenv i https mirrors aliyu

随机推荐

  • 开源技术选型手册 (china-pub 首发) -目 录

    第1章c闲话开源社区篇cc 第2章cWeb框架篇cc 2 1cStrutsc 2 2cSpringc 2 3cSeamcc 第3章c开源Web服务器c 3 1cApachecc 3 2cLighttpdcc 3 3cNginxc 第4章c应
  • 【MySQL】varchar转int类型的方法

    MySQL varchar转int类型的方法 CAST函数的使用 1 问题描述 获取一个表user中age的最大值 由于历史原因 age是varchar类型的 2 问题解决 方案一 select max cast sex as UNSIGN
  • Blender辅助工具集:M3插件

    1 MACHIN3tools M3 插件 一个辅助工具集 MACHIN3tools An Addon to Streamline Blender 3 3 and beyond by machin3 io https github com m
  • Spring(DI)

    DI Dependency Injection 即依赖注入 对象之间的依赖由容器在运行期决定 即容器动态的将某个依赖注入到对象自重 基于XML配置注入依赖 有参构造函数注入依赖 bean类实现有参构造函数 public class Stud
  • 开始在CSDN上安家了哈!

    2014年计划完成50 原创blog 这是我的目标
  • vue项目打包部署到tomcat(详细)

    hash路由模式打包部署到tomcat 1 修改config index js文件下的assetsPublicPath为 2 修改router文件夹下index js添加 base 文件夹名称 例如 yuncheng 可以自己随意设置 3
  • 未找到 van-toast 节点,请确认 selector 及 context 是否正确

    1 json文件引入 van toast vant weapp toast index 2 js文件引入 import Toast from vant weapp toast toast 3 wxml写入
  • 微信小程序蓝牙BLE开发实战——遇到问题及踩坑(三)

    微信小程序蓝牙BLE开发实战 三 对于我这种小白 遇到问题是常见的哈 这里记录下 避免日后再踩坑 文章目录 微信小程序蓝牙BLE开发实战 三 1 iPhone6及6plus无法搜索到设备 解决方案 2 IOS无法获取 mac 地址 如何连接
  • 分布式任务调度平台xxl-job

    一 java的集中式任务调度 while true Thread sleep 轮询 线程休眠的方式实现定时任务 java util Timer java util TimerTask Timer是一种定时器工具 用于使用后台线程计划执行指定
  • 数字IC设计流程学习笔记

    一 规格定制 IC的规格定制包括物理指标 性能指标和功能指标 物理指标 封装 工艺 芯片面积 性能指标 功耗 速度 功能指标 接口 芯片功能 二 系统设计 系统设计是确定IC的算法模型和系统架构等 并通过一些高级语言 matlab等对算法模
  • 【tensorflow基础】读取mnist数据

    转载于 MNIST手写数字数据集读取方法 TensorFlow的封装让使用MNIST数据集变得更加方便 MNIST数据集是NIST数据集的一个子集 它包含了60000张图片作为训练数据 10000张图片作为测试数据 在MNIST数据集中的每
  • spring-security

    文章目录 csrf remember me 密码存储 权限继承 应 要求添加的代码 白名单相关说明 csrf A网站登录 B网站 使用 Copyright C
  • 传染病模型(4)——SIRS模型和SIER模型及matlab具体程序

    前言 常见的传染病模型按照具体的传染病的特点可分为 SI SIS SIR SIRS SEIR 模型 其中 S E I R 的现实含义如下 S Susceptible 易感者 指缺乏免疫能力健康人 与感染者接触后容易受到感染 E Expose
  • 一文了解亚马逊云科技适用于 Amazon Lightsail 的托管数据库

    Amazon Lightsail 是亚马逊云科技提供的一种易上手使用 月度价格经济实惠 并包括了计算实例 容器 存储 数据库的虚拟专用服务器 在创建时可以进行业务蓝图选择 可选择包含多种操作系统 Linux Windows 等 或操作系统加
  • C++中定义常量的几种方式

    概述 在程序运行过程中 始终不发生改变的量 称之为常量 在 C 语言中常量是个固定值 也就是说常量值在定义后不能进行修改 define 宏常量 define 是 C 语言中定义常量的方式 在 C 中也可以使用 define 的使用 defi
  • RocketMQ安装与启动

    分享知识 传递快乐 官网 https rocketmq apache org 1 准备环境 系统 Centos7 jdk 1 8 2 环境部署 解压 rocketmq 并进入 rocketmq 下的 bin 目录 调整启动内存 vim bi
  • C++ 函数模板

    函数模板是通用的函数描述 它们使用泛型来定义函数 其中的泛型可用具体的类型替换 通过将类型作为参数传递给模板 可使编译器生成该类型的函数 由于模板允许以泛型 而不是具体类型 的方式编写程序 因此有时候也被称为通用编程 在标准C 98添加关键
  • ubuntu14.04安装wireshakes

    网络攻防 这课要做一个嗅探器的大作业 想在linux是实现 于是先在ubuntu上下一个wiresharks看看它的一些功能和 废话少说 直接上安装过程与期间遇到的问题 安装编译工具 sudo apt get install build e
  • Spring Gateway集成 Nacos注册中心不能够发现服务的问题解决

    一 问题描述 我们现在是在用Nacos替换Eureka 原来Eureka和Spring gateway运行正常 可以通过Spring gateway调用注册到Eureka中的服务 当前Spring cloud的版本是Hoxton SR8 N
  • 顺序表基本操作

    文章目录 1 顺序表插入元素 2 顺序表删除元素 3 顺序表查找元素 4 顺序表更改元素 1 顺序表插入元素 向顺序表中插入数据元素 根据插入位置的不同 可分为以下 3 种情况 插入到顺序表的表头 在表的中间位置插入元素 尾随顺序表中已有元