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

news2024/11/26 9:55:18

目录

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

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

三.顺序表的插入

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嘉实基金:金融科技与开源治理的双驱动,打造安全的资管业务数字系统

嘉实基金成立于1999年&#xff0c;是国内最早成立的十家基金管理公司之一&#xff0c;也是国内首家资产管理规模超过千亿的基金公司。作为一家领先的投资管理公司&#xff0c;嘉实基金也在数字化转型趋势中&#xff0c;积极推进金融科技在金融资管行业中的探索实践。为了支撑基…

7-zip 更换图标:定制你的7-Zip

7-Zip Theme Manager是一个用于管理和应用自定义主题的软件工具&#xff0c;专门为7-Zip文件压缩软件开发。它允许用户选择并应用各种主题来改变7-Zip的外观和用户界面&#xff0c;包括颜色方案、图标集、按钮样式等。通过更改主题&#xff0c;用户可以使7-Zip界面更加美观、易…

【PostgreSQL的CLOG解析】

同样还是这张图&#xff0c;之前发过shared_buffer和os cache、wal buffer和work mem的文章&#xff0c;今天的主题是图中的clog&#xff0c;即 commit log&#xff0c;PostgreSQL10之前放在数据库目录的pg_clog下面。PostgreSQL10之后修更名为xact,数据目录变更为pg_xact下面&…

【 运维这些事儿 】- Gerrit代码审查详

文章目录 背景作用代码审查工具Gerrit镜像构建Dockerfile 部署配置 Gitlab代码同步ssh-agent 相关概念常用命令Git 配置使用 Git Review针对已有项目添加commit-msg&#xff0c;用于自动添加changeId添加源配置 .gitreview备注指定审核人自定义git命令 开发使用代码审查 背景 …

image has dependent child images

问题&#xff1a;很多none的镜像无法被删除 解决过程&#xff1a; 1、通过 docker image prune -f 提示可删除为 0 2、直接进行删除报错&#xff1a; docker rmi 8f5116cbc201Error response from daemon: conflict: unable to delete 8f5116cbc201 (cannot be forced) - im…

面试题-React(一):React是什么?它的主要特点是什么?

探索React&#xff1a;前端开发中的重要角色与主要特点 引言&#xff1a; 在现代前端开发领域&#xff0c;React已经成为最受欢迎和广泛使用的JavaScript库之一。它由Facebook开发并于2013年首次发布。随着时间的推移&#xff0c;React在开发社区中获得了强大的支持和认可。本…

对锁的理解

悲观锁和乐观锁 每次操作的时候都在上锁解锁&#xff0c;能解决并发中的各种问题&#xff0c;不支持并发操作&#xff0c;效率低 每次操作都加上版本号&#xff0c;操作提交的时候会比较数据库版本和目前的版本号是否一致&#xff0c;不一致就会提交失败 表锁和行锁 表锁是对…

Joint HDR Denoising and Fusion: A Real-World Mobile HDR Image Dataset

Abstract 手机已经成为我们日常生活中无处不在、不可或缺的拍照设备&#xff0c;而小光圈和传感器尺寸使得手机更容易受到噪点和过饱和的影响&#xff0c;导致动态范围(LDR)低、画质低。 因此&#xff0c;为手机开发高动态范围(HDR)成像技术至关重要。 然而&#xff0c;现有的…

SpringBean的生命周期和循环依赖

Spring循环依赖 前言 大制作来啦&#xff0c;spring源码篇&#xff0c;很早之前我就想写一系列spring源码篇了&#xff0c;正好最近总是下雨&#xff0c;不想出门&#xff0c;那就让我来带大家走进Spring源码世界吧。 阅读建议 spring源码读起来有点难度&#xff0c;需要多Deb…

性价比最高的护眼灯,护眼台灯应该怎么挑选

随着技术的发展&#xff0c;灯光早已成为每家每户都需要的东西。但是灯光不好可能会对眼睛造成伤害是很多人没有注意到的。现在随着护眼灯产品越来越多&#xff0c;市场上台灯的选择越来越多样化&#xff0c;如何选择一个对眼睛无伤害、无辐射的台灯成为许多家长首先要考虑的问…

limereport报表使用

在这里我使用报表是以报表的形式显示数据库的信息。所以首先需要准备的资料有&#xff1a;limereport源码&#xff0c;还有数据库&#xff0c;我这里使用的是qsqlite数据库。 1、下载limereport报表源码 2、运行自带的案例&#xff1a;demo_r1 3、点击 “Run Report Designer”…

RedisDesktopManager连不上redis问题解决(小白版)

常见问题就是 redis.conf配置文件 a.将port 127.0.0.1这一行注释掉 b.protected-mode保护模式改为no 这个可以看到很多博主都说了&#xff0c;相信都搜到这里来了你们都弄了&#xff0c;我就不详细说了 防火墙开放端口 我说明我自己的问题以及解决方法 1、执行telnet 虚拟…

2023年8月第1~2周大模型荟萃

2023年8月第1~2周大模型荟萃 2023.8.14版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、黑客制造了一款基于 AI 的恶意工具 FraudGPT 早先&#xff0c;有黑客制作了一个“没有道德限制”的 WormGPT 聊天机器人&#xff0c;可以自动生成…

PDF文件限制编辑怎么取消?

PDF文件设置了限制编辑&#xff0c;想要取消PDF文件的限制编辑&#xff0c;很简单&#xff0c;打开PDF编辑器&#xff0c;点击工具栏中的文件&#xff0c;选择属性按钮&#xff0c;进入到熟悉感界面之后&#xff0c;点击安全&#xff0c;然后我们点击权限下拉框&#xff0c;选择…

ModaHub魔搭社区:Milvus Cloud向量数据库可以部分避免AI幻觉

向量数据库的技术优势使其更适合在AI场景下应用&#xff0c;能够为AI的开发、增强内容生成的准确性提供重要的技术支撑。进一步来讲&#xff0c;向量数据库也被看作是大语言模型的记忆与灵魂&#xff0c;对于解决大模型的“幻觉”问题至关重要。 由于大模型是基于已有数据训练而…

TB/TM-商品详情原数据(APP)

一、接口参数说明&#xff1a; item_get_app-获得TB/TMapp商品详情原数据&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_get_app 名称类型必须描述keyString是调用key&…

java+springboot+mysql员工管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的员工管理系统&#xff08;人力资源管理系统&#xff09;&#xff0c;系统包含超级管理员、管理员、员工角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;部门管理&#xff1b;职位管理…

嵌入式面试笔试刷题(day10)

文章目录 前言一、数组和链表的区别二、什么是内存对齐三、IIC的时序四、static作用五、查看tty设备的方法六、查找指定文件命令七、三次握手和四次挥手1.三次握手2.四次挥手 八、半关闭状态九、字节流和数据报总结 前言 本篇文章继续讲解笔试和面试。 一、数组和链表的区别 …

C++ STL stack queue

目录 一.stack 介绍 二.stack 使用 三.stack 模拟实现 普通版本&#xff1a; 适配器版本&#xff1a; 四.queue的介绍 五. queue使用 六.queue模拟实现 七.deque介绍 1.容器适配器 2.deque的简单介绍 3.deque的缺陷 4.为什么选择deque作为stack和queue的底层默认容…

SpringBoot复习:(46)全局的bean懒加载是怎么实现的?

在application.properties中配置&#xff1a; spring.main.lazy-initializationtrue在运行SpringApplication的run方法时&#xff0c;代码如下&#xff1a; 其中调用了prepareContext,prepareContext代码如下&#xff1a; 当在配置文件中配置了spring.main.lazy-initializat…