顺序表的插入,删除,修改和查找(详细解析)

目录

一.顺序表的初始化----静态分配

二.顺序表的初始化----动态分配

三.顺序表的插入

1.插入操作

2.插入操作的时间复杂度

三.顺序表的删除操作

1.顺序表的删除

 2.删除操作的时间复杂度

四.顺序表的查找

1.按位查找操作:查找第i位置的元素

2.按位查找操作的时间复杂度:O(1)

3.按值查找操作

4.按值查找的时间复杂度


一.顺序表的初始化----静态分配

#include<stdio.h>
#define MaxSize 10
typedef struct{
    int data[MaxSize];
    int length;
}SqList;

void InitList(SqList &L)
{
    for(int i=0;i<length;i++)  
        L.data[i]=0;
    L.length=0;

}

int main()
{
    SqList L;
    InitList(L);
    return 0;
}

不能写为

#include<stdio.h>
#define MaxSize 10
typedef struct{
    int data[MaxSize];
    int length;
}SqList;

void InitList(SqList &L)
{
    L.length=0;
}

int main()
{
    SqList L;
    InitList(L);
    for(int i=0;i<MaxSize;i++)
    {
        printf("data[%d]=%d\n",i,L.data[i]);
    }
    return 0;
}

结果为

 其中有两个错误

1.未初始化数据

因为在初始化时没有设置数据元素的默认值,内存中会出现上述“4203657”,“21”这类遗留脏数据

2.i<MaxSize

上述代码中的i<MaxSize操作其实是不合理的,应该访问到顺序表的最后一个元素截止,不应该访问大于数据表长度的元素,即i<L.length

若L.length>MaxSize会报错,若将MaxSize设的稍微大些,有可能造成内存的浪费,所以最好的解决方式就是动态内存分配

二.顺序表的初始化----动态分配

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

#define InitSize 10
typedef struct{
    int *data;//指示动态分配数组的指针:L.data=(int *)malloc(InitSize*sizeof(int));
    int MaxSize;//顺序表的最大容量
    int length;//顺序表的当前长度

}SeqList;

void InitList(SeqList &L)
{
//申请一段连续的存储空间
    L.data=(int*)malloc(InitSize*sizeof(int));
    L.length=0;
    L.MaxSize=InitSize;

}

//开辟一段新的空间
void IncreaseSize(SeqList &L,int len)
{
    int *p=L.data;
    L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
    for(int i=0;i<L.length;i++)
    {
        L.data[i]=p[i];//将数据复制到新区域
//虽然动态分配能让数据表的大小灵活的改变,但是会增大时间开销
    }
    L.MaxSize=L.MaxSize+len;
    free(p);

}

int main()
{
    SeqList();
    InitList();
    IncreaseSize(L,5);
    return 0;

}

 

free函数会将*p(p指针)所指向的整块存储空间释放,归还给系统,同时p是一个局部变量,当这个函数结束后,p这个变量的存储空间也将被释放 

三.顺序表的插入

1.插入操作

#define MaxSize 10    //定义最大长度
typedef struct
{
    ElemType data[MaxSize];
    int length;//顺序表当前长度
}SqList;//顺序表类型定义


void ListInsert(SqList &L,int i,int e)
{
    for(int j=L.length;j>=i;j--)//将第i个元素及之后的元素后移
        L.data[j]=L.data[j-1];
    L.data[i-1]=e;
//将需要插入的元素赋值e,因为数组从L.data[0]开始,所以这里第i个元素是[i-1]表示的
    L.length++;
}

int main()
{
    SqList L;//声明一个顺序表
    InitList(L);
    ListInsert(L,3,3);//在三个位置插入数据元素3


}

 如下图所示,表示ListInsert(L,3,3)

 若执行ListInsert(L,9,3),则会产生如下现象

 中间的值data[6],data[7]空了,而在顺序表中元素应该相邻存放,说明这段代码不够健壮,应该做如下调整

bool ListInsert(SqList &L,int i,int e)
{
    if(i<1||i>L.length+1)//判断i的范围是否有效
        return false;
    if(L.length>=MaxSize)//判断当前存储空间是否已满
        return false;
    for(int j=L.length;j>=i;j--)
    {
        L.data[j]=L.data[j-1];
    }
    L.data[i-1]=e;
    L.length++;
    return true;
}

2.插入操作的时间复杂度

最好情况:新元素插入到表尾,不需要移动元素
i= n+1,循环0次;最好时间复杂度=O(1);

最坏情况:新元素插入到表头,需要将原有的n个元素全都向后移动

i= 1,循环 n 次;最坏时间复杂度O(n);

平均情况:假设新元素插入到任何一个位置的概率相同,即i= 1,2,3,...,length+1 的概率都是 p=1/n+1,i= 1,循环 n 次;i=2 ,循环 n-1,i+3,循环n-2次,.....i=n+1时,循环0次
平均循环次数 =np +(n-1)p +(n-2)p + 1*p=(n(n+1)/2)*(1/n+1)=n/2

三.顺序表的删除操作

1.顺序表的删除

bool ListDelete(SqList &L,int i,int &e)
{
    if(i<1||i>L.length)
        return false;
    e=L.data[i-1];
    for(int j=i;j<L.length;j++)
    {
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}

int main()
{
    SqList L;
    InitList(L);
    int e=-1;
    if(ListDelete(L,3,e))
        printf("已删除第3个元素,删除元素值为=%d\n",e);
    else
        printf("位序i不合法,删除失败\n");
    return 0;

}

插入

for(int j=L.length;j>=i;j--)//从后到前依次往后挪

 

删除

for(int j=i;j<L.length;j++)//从前到后依次往前挪

 

 2.删除操作的时间复杂度

最好情况:删除表尾元素,不需要移动其他元素
i= n,循环 0 次;最好时间复杂度 = O(1)

最坏情况:删除表头元素,需要将后续的 n-1 个元素全都向前移动

i= 1,循环 n-1 次;最坏时间复杂度 = O(n);

平均情况:假设删除任何一个元素的概率相同,即i= 1,2,3,...,length 的概率都是 p=1/n

平均循环次数 =(n-1)p +(n-2)p + 1*p=(n(n-1)/2)*(1/n)=n-1/2

四.顺序表的查找

1.按位查找操作:查找第i位置的元素

#define InitSize 10    //顺序表的初始长度
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
    int *data;    //指示动态分配数组的指针
    int MaxSize;
    int length;
}SeqList;

void InitList(SeqList &L)
{
    L.data=(int *)malloc(InitSize*sizeof(int));
    L.length=10;
    L.MaxSize=InitSize;
}

int GetElem(SeqList L,int i)
{
    return L.data[i-1];
}

int main()
{
	SeqList L;
	InitList(L); 
	for(int i=0;i<L.length;i++)
		L.data[i]=i;
	int a;
	printf("请输入您要查找的位置:"); 
	scanf("%d",&a);
	printf("第%d个元素是%d\n",a,L.data[a-1]);
	return 0;
		
}

2.按位查找操作的时间复杂度:O(1)

3.按值查找操作

#define InitSize 10
#include<stdio.h>
#include<stdlib.h>

typedef struct{
    int *data;
    int MaxSize;
    int length;
} SeqList;

void InitList(SeqList &L)
{
    L.data = (int *)malloc(InitSize * sizeof(int));
    L.length = 10;
    L.MaxSize = InitSize;
}

// 在顺序表L中查找第一个元素值等于e的元素,并返回其位序
int LocateElem(SeqList L, int e)
{
    for(int i=0; i<L.length; i++)
    {
        if(L.data[i] == e)
            return i + 1; // 数组下标为i的元素值等于e,返回其位序为i+1
    }
    return 0; // 未找到该元素,返回0
}

int main()
{
    SeqList L;
    InitList(L);
    for(int i=0; i<L.length; i++)
    {
        L.data[i] = i; // 给顺序表赋值
    }

    int e = 9;
    int a = LocateElem(L, 9); // 在顺序表L中查找元素9
    if(a != 0)
    {
        printf("该值位于%d\n", a); // 找到该值,输出它的位序
    }
    else
    {
        printf("未找到该值!\n"); // 未找到该值,输出提示信息
    }
    return 0;
}

4.按值查找的时间复杂度

最好情况:目标元素在表头
循环1次;最好时间复杂度 = O(1)

最坏情况:目标元素在表尾

循环 n 次;最坏时间复杂度 = O(n);
平均情况:假设目标元素出现在任何一个位置的概率相同,都是1/n
目标元素在第1位,循环1次;在第2位,循环2次;在第 n位,循环 n 次...... ;
平均循环次数 =1*1/n +1/n*2 +1/n*3 + =(n(n+1)/2)*(1/n)=n+1/2

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++字符串函数

在 C 中有大量用于操作 C-style 字符串的函数&#xff0c;它们集成在头文件 <cstring> 中。其常见的函 函数作用strcpy(s1,s2) 复制字符串 s2 到 s1strcat(s1,s2) 将字符串 s2 连接到 s1 末尾strlen(s) 计算字符串 s 长度strcmp(s1,s2) 比较字符串 s1 和 s2 …

DoIP诊断入门

简介 DoIP&#xff08;Diagnosis over Internet Protocol&#xff09;是一种用于车辆诊断的网络通信协议。它基于现代互联网技术&#xff0c;允许通过以太网或IP网络进行车辆诊断和通信。 DoIP的背景是现代车辆中使用的电子控制单元&#xff08;ECU&#xff09;数量不断增加&…

内网穿透——使用Windows自带的网站程序建立网站

文章目录 1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试 3. Cpolar内网穿透3.1 下载安装Cpolar3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5.结语 1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xff0c;比如…

vite创建打包预览Vue3流程

本文章只是走了一下创建》运行》打包》预览打包效果的流程步骤&#xff0c;不包含创建后配置vue3项目和打包优化等。 1.使用vite创建vue3项目 创建项目命令&#xff1a; npm init vitelatest写完项目名称后回车 键盘上下键选择Vue构建 根据项目需求选择ts还是js 创建完成 根…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(8 月 8 日论文合集)

文章目录 一、检测相关(13篇)1.1 FSD V2: Improving Fully Sparse 3D Object Detection with Virtual Voxels1.2 Dimensionality Reduction for Improving Out-of-Distribution Detection in Medical Image Segmentation1.3 FeatEnHancer: Enhancing Hierarchical Features for…

如何显示virtualBox中的菜单栏

1.菜单栏未显示&#xff0c;如何显示&#xff1f; 2&#xff0c;按下ctrl(右边)HOME&#xff0c;弹出菜单&#xff0c;如下图所示&#xff1a;选择视图-菜单栏-显示菜单栏 3.OK:完成&#xff01;

【深度学习 video detect】Towards High Performance Video Object Detection for Mobiles

文章目录 摘要IntroductionRevisiting Video Object Detection BaselinePractice for Mobiles Model Architecture for MobilesLight Flow 摘要 尽管在桌面GPU上取得了视频目标检测的最近成功&#xff0c;但其架构对于移动设备来说仍然过于沉重。目前尚不清楚在非常有限的计算…

福利!百度Workshop实战课,即刻搭建AI原生应用!| IDCF

你是否希望掌握大模型开发的秘诀&#xff1f;你是否渴望得到实践操作的机会&#xff1f;如果你的心中充满热情和期待&#xff0c;那么&#xff0c;WAVE SUMMIT 2023特别设置的Workshop将会是你的知识启航站&#xff01; 本次Workshop专注于AI开发与大模型应用&#xff0c;邀请…

【Docker】个人镜像文件Dockerfile制作详解

前言 洁洁的个人主页 我就问你有没有发挥&#xff01; 知行合一&#xff0c;志存高远。 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是…

分布式链路追踪概述

分布式链路追踪概述 文章目录 分布式链路追踪概述1.分布式链路追踪概述1.1.什么是 Tracing1.2.为什么需要Distributed Tracing 2.Google Dapper2.1.Dapper的分布式跟踪2.1.1.跟踪树和span2.1.2.Annotation2.1.3.采样率 3.OpenTracing3.1.发展历史3.2.数据模型 4.java探针技术-j…

不同版本Idea部署Maven和Tomcat教学

目录 一、2019版Idea 1.1. Maven配置 1.2. Tomcat配置 二、2023版Idea 2.1 Maven配置 2.2. Tomcat配置 一、2019版Idea 1.1. Maven配置 在这篇 http://t.csdn.cn/oetKq 我已经详细讲述了Maven的下载安装及配置&#xff0c;本篇就直接开始实操 : 1. 首先进入设置搜索Mave…

每天一道leetcode:115. 不同的子序列(动态规划困难)

今日份题目&#xff1a; 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数。 题目数据保证答案符合 32 位带符号整数范围。 示例1 输入&#xff1a;s "rabbbit", t "rabbit" 输出&#xff1a;3 解释&#xff1a; 如下所…

竞赛项目 深度学习验证码识别 - 机器视觉 python opencv

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x…

vue3中用watch监听响应式数据的注意点

如果你在vue3中使用reactive()方法创建响应式数据&#xff0c;然后又用torefs()方法将响应式数据解构成单一的ref响应式数据。 此时&#xff0c;如果你想用watch监听解构出来单一的响应式数据&#xff0c;watch不起作用。 此时&#xff0c;你需要用watch监听之前的reactive()…

【金融量化】对企业进行估值的方法有哪些?

估值的方法有哪些&#xff1f; 如何对企业进行估值&#xff1f;有2个方法估算。 1 绝对估值法 它是一种定价模型&#xff0c;用于计算企业的内在价值。 比如说你可以根据公司近N年的现金流情况。借此去预测未来N年的现金流情况。所有的现金流数据都可以在年报上查询到。最后…

《TCP IP网络编程》第十六章

第 16 章 关于 I/O 流分离的其他内容 16.1 分离 I/O 流 「分离 I/O 流」是一种常用表达。有 I/O 工具可区分二者&#xff0c;无论采用哪种方法&#xff0c;都可以认为是分离了 I/O 流。 2次 I/O 流分离&#xff1a; 第一种是第 10 章的「TCP I/O 过程」分离。通 shutdown(soc…

【electron】electron安装过慢和打包报错:Unable to load file:

文章目录 一、安装过慢问题:二、打包报错&#xff1a;Unable to load file: 一、安装过慢问题: 一直处于安装过程 【解决】 #修改npm的配置文件 npm config edit#添加配置 electron_mirrorhttps://cdn.npm.taobao.org/dist/electron/二、打包报错&#xff1a;Unable to load…

在 Windows 上安装 OpenCV – C++ / Python

在这篇博文中&#xff0c;我们将在 Windows 上安装适用于 C 和 Python 的 OpenCV。 C 安装是在自定义安装 exe 文件的帮助下完成的。而Python的安装是通过Anaconda完成的。 在 Windows 上安装 OpenCV – C / Python&#xff08;opencv官方Wndows上安装openCV- C/ Pthon 的链接…

SpringBoot复习:(43)如何以war包的形式运行SpringBoot程序

一、.pom.xml配置packging为war <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven…

Unity3D高级编程:主程手记学习1

第一章 软件架构 Untiy 分层设计 分层后再分治