【数据结构】线性表 顺序表(动态、静态分配,插入删除查找基本操作)解析+完整代码

1.线性表的基本概念

  • 定义

    线性表(Linear List)是具有相同数据类型的n个数据元素的有限序列

    • n为表长,n=0时线性表是个空表
  • 前驱、后继

    • 前驱:其中一个数据元素的前一个元素。第一个元素没有前驱。
    • 后继:其中一个数据元素的后一个元素。最后一个元素没有后继。
  • 存储/物理结构

    • 顺序表(顺序存储)
    • 链表(链式存储)

2.顺序表

2.1 顺序表的定义

  • 顺序表定义

    用顺序存储方式实现线性表的储存。

    是用一组地址连续的存储单元依次存储线性表中的数据元素。

    • 特点:

      1.表中元素的逻辑顺序与物理顺序相同。

      2.可以随机存取——知道顺序表起始位置LOC(A)和每个元素所占内存的大小sizeof(ElemType)后,可知道任意一个元素的位置。

  • 优点

    1.可随机访问,O(1)时间内找到指定元素;

    2.存储密度高,每个结点只存储数据元素。

  • 缺点

    1.元素的插入和删除要移动大量数据元素。

    2.需要连续存储空间,不够灵活。

2.1.1 静态分配
//静态分配结构存储
#define MaxSize 10 //最大长度
typedef struct{int data[MaxSize]; //静态数组存放数据元素int length; //顺序表当前长度
}SqList; //顺序表类型定义//静态分配初始化
void InitList(SqList &L){L.Length=0;
}
  • 如果数组存满怎么办?

    没办法了,因为顺序表表长刚开始确定后就无法改变,∴有了动态分配

2.1.2 动态分配
//动态分配结构存储
#define InitSize 100 //表长度的初始定义
typedef struct{ElemType *data; //指示动态分配数组的指针int MaxSize; //最大容量int length; //当前个数
}SeqList;//动态分配初始化
void InitList(SeqList &L){L.data=(ElemType*)malloc(MaxSize*sizeof(ElemType));L.length=0;L.MaxSize=InitSize;
}

C动态分配语句

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
free(L.data);

C++动态分配语句

L.data=new ElemType[InitSize];
delete[]指针变量名;
或
delete 指针变量名;
  • 增加动态数组长度

    void IncreaseSize(SeqList &L,int len){int *p=L.data; //将表中数据存储到p中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);
    }
    
  • 注:动态分配不是链式存储,同样顺序存储,只是空间大小可变。

2.2 顺序表的插入

  • 原理

    在线性表L的第i个位置插入元素e:

    将第i个元素及其后面的所有元素向后移一位,腾出空位插e。

    >

//在L的位序i处插入元素e
bool ListInsert(SqList &L,int i,int e){//判i范围是否有效if(i<1||i>L.length+1)return false;//判存储空间是否已满if(L.length>=MaxSize)return false;//将第i个元素及之后元素后移for(int j=L.length;j>=i;j--) {L.data[j]=L.data[j-1]; //注意:位序和数组下标的关系,并从后面元素依次移动}L.data[i-1]=e;L.length++;return true;
}
  • 时间复杂度

    • 最好情况:在表尾插入,元素后移不用执行,O(1)。
    • 最坏情况:在表头插入,元素后移执行n次,O(n)。
    • 平均情况:O(n/2),即O(n)。

2.3 顺序表的删除

  • 原理

    删除顺序表L中的第i个元素:

    将被删元素赋给引用变量e,将第i+1个元素及其后的所有元素往前移一位。

//删除L中的第i个元素,并用返回
bool ListDelete(SqList &L,int i,ElemType &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;
}
  • 时间复杂度

    • 最坏情况:删除表尾元素,无需移动元素,O(1)。
    • 最好情况:删除表头元素,需移动除表尾外的所有元素,O(n)。
    • 平均情况:O(n/2),即O(n)。

2.4 顺序表的查找

2.4.1 按位查找
ElemType GetElem(SqList L,int i){return L.data[i-1];
}
  • 时间复杂度:O(1)
2.4.2 按序查找
int LocateElem(SqList L,ElemType e){int i;for(i=0;i<L.length;i++){if(L.data[i]==e)return i+1; //找到了返回位序}return 0; //没找到返回0
}
  • 时间复杂度:O(n)

*完整代码 顺序表静态存储

//顺序表 静态分配 线性表下标从0开始
#include<stdio.h>#define ElemType int//静态结构体
#define MaxSize 99
typedef struct {ElemType data[MaxSize];int length;
}SqList;//初始化
void InitList(SqList &L)
{L.length = 0;
}//求表长
int Length(SqList &L) 
{return L.length;
}//按值查找
int LocateElem(SqList &L,ElemType e) 
{for (int i = 0; i < L.length; i++) {if (L.data[i] == e) {return i + 1;}}return 0;
}//按位查找
int GetItem(SqList& L, int i) 
{return L.data[i-1]; //i是位序,而顺序表从0开始存的,所以i要-1
}//插入操作
bool ListInsert(SqList& L, int i, ElemType e) 
{if (i<1 || i>L.length)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;
}//删除操作
bool ListDelete(SqList& L, int i, ElemType& 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;
}//判空操作
bool Empty(SqList& L)
{if (L.length == 0)return true;elsereturn false;
}//销毁操作
void DestroyList(SqList &L)
{L.length = 0;
}//输出
void PrintList(SqList& L) 
{for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");
}int main()
{SqList L;InitList(L);//赋值for (int i = 0; i < 10; i++){L.data[i] = i;L.length++;}PrintList(L);printf("插入:\n");int e = -1, pos = 4;ListInsert(L, pos , e);PrintList(L);printf("删除:\n");int a;ListDelete(L, pos, a);PrintList(L);printf("%d\n", a);printf("按值查找:\n");pos = LocateElem(L, 5);printf("%d\n", pos);printf("按位查找:\n");printf("%d", GetItem(L, 3));
}

请添加图片描述

*完整代码 顺序表动态存储

//顺序表 动态分配 
#include<stdio.h>
#include <stdlib.h>#define ElemType int//静态结构体
#define InitSize 2
typedef struct {ElemType *data;int length;int MaxSize;
}SeqList;//初始化
void InitList(SeqList& L)
{L.data = (ElemType*)malloc(InitSize * sizeof(ElemType));L.length = 0;L.MaxSize = InitSize;
}//增加动态数组长度
void IncreaseSize(SeqList& L, int len) {int* p = L.data; //将表中数据存储到p中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 Length(SeqList& L)
{return L.length;
}//按值查找
int LocateElem(SeqList& L, ElemType e)
{for (int i = 0; i < L.length; i++){if (L.data[i] == e){return i + 1;}}return 0;
}//按位查找
int GetItem(SeqList& L, int i)
{return L.data[i - 1]; //i是位序,而顺序表从0开始存的,所以i要-1
}//插入操作
bool ListInsert(SeqList& L, int i, ElemType e)
{if (i<1 || i>L.length)return false;if (L.length >= L.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;
}//删除操作
bool ListDelete(SeqList& L, int i, ElemType& 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;
}//判空操作
bool Empty(SeqList& L)
{if (L.length == 0)return true;elsereturn false;
}//销毁操作
void DestroyList(SeqList& L)
{free(L.data);L.data = NULL; // 避免悬挂指针L.length = 0;
}//输出
void PrintList(SeqList& L)
{for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");
}int main()
{SeqList L;InitList(L);IncreaseSize(L, 9);//赋值for (int i = 0; i < 10; i++){L.data[i] = i;L.length++;}PrintList(L);printf("插入:\n");int e = -1, pos = 5;ListInsert(L, pos, e);PrintList(L);printf("删除:\n");int a;ListDelete(L, pos, a);PrintList(L);printf("%d\n", a);printf("按值查找:\n");pos = LocateElem(L, 5);printf("%d\n", pos);printf("按位查找:\n");printf("%d", GetItem(L, 3));DestroyList(L);
}

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

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

相关文章

设计并实现一个并发安全的LRU(Least Recently Used,最近最少使用)缓存结构

文章目录 前言实战演示写在最后 前言 相信很多人都使用过LinkedHashMap&#xff0c;LinkedHashMap中的removeEldestEntry可以删除老旧的元素&#xff0c;我们可以以此来实现一个LRU缓存结构&#xff0c;并结合java中JUC包中的各种多线程锁机制来保证多线程安全。 以下是我遇见…

AE电源Apex Generator 系列5708009-C 使用说明 文件内容可以看目录,包含使用,调试,安装等内容都有160页

AE电源Apex Generator 系列5708009-C 使用说明 文件内容可以看目录&#xff0c;包含使用&#xff0c;调试&#xff0c;安装等内容都有160页

【简写Mybatis】02-注册机的实现以及SqlSession处理

前言 注意&#xff1a; 学习源码一定一定不要太关注代码的编写&#xff0c;而是注意代码实现思想&#xff1a; 通过设问方式来体现代码中的思想&#xff1b;方法&#xff1a;5W1H 源代码&#xff1a;https://gitee.com/xbhog/mybatis-xbhog&#xff1b;https://github.com/xbh…

Unity Shader - sahder变体剔除

文章目录 吐槽优化方案 - 目前最靠谱的方式shadercsharp 吐槽 我之所以单独写这边文章&#xff0c;是因为之前写的一篇&#xff1a; Unity Shader - Built-in管线下优化变体&#xff0c;编辑后&#xff0c;无法保存&#xff0c;一直提示&#xff1a;操作超时。 等了差不多 3…

跨端轻量JavaScript引擎的实现与探索

一、JavaScript 1.JavaScript语言 JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。 ECMAScript发展史: 时间版本说明1997年7月ES1.0 发布当年7月&#xff0c;ECMA262 标准出台1998年6月ES2.0 发布该版本修改完全符合…

Flutter Version Manager (FVM): Flutter的版本管理终极指南

Flutter笔记 Flutter Version Manager (FVM) - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/article/details/136300307 my-websit…

Sentinel 动态规则扩展

一、规则 Sentinel 的理念是开发者只需要关注资源的定义&#xff0c;当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则&#xff1a; 通过 API 直接修改 (loadRules)通过 DataSource 适配不同数据源修改 手动通过 API 修改比较直观&#xff0c;…

pytorch保存张量为图片

这里用到的是torchvision中的save_image。 废话不多说&#xff0c;直接来代码&#xff1a; import torch from torchvision.utils import save_image B, C, H, W 64, 3, 32, 32 input_tensor torch.randn(B, C, H, W) save_image(input_tensor, "hh.png", nrow8)…

HarmonyOS—低代码开发Demo示例

接下来为大家展示一个低代码开发的JS工程的Demo示例&#xff0c;使用低代码开发如下华为手机介绍列表的HarmonyOS应用/服务示例。 1.删除模板页面中的控件后&#xff0c;选中组件栏中的List组件&#xff0c;将其拖至中央画布区域&#xff0c;松开鼠标&#xff0c;实现一个List组…

【HarmonyOS】鸿蒙开发之Stage模型-应用配置文件——第4.2章

Stage模型-应用配置文件 AppScope -> app.json5&#xff1a;应用的全局配置信息entry&#xff1a;OpenHarmony工程模块&#xff0c;编译构建生成一个HAP包 build&#xff1a;用于存放OpenHarmony编译生成的hap包src -> main -> ets&#xff1a;用于存放ArkTS源码src …

【wu-lazy-cloud-network】Java自动化内网穿透架构整理

项目介绍 wu-lazy-cloud-network 是一款基于&#xff08;wu-framework-parent&#xff09;孵化出的项目&#xff0c;内部使用Lazy ORM操作数据库&#xff0c;主要功能是网络穿透&#xff0c;对于没有公网IP的服务进行公网IP映射 使用环境JDK17 Spring Boot 3.0.2 版本更新 1…

【51单片机】红外遥控红外遥控电机调速(江科大)

1.红外遥控简介 红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出 通信方式:单工,异步 红外LED波长:940nm 通信协议标准:NEC标准 2.硬件电路 红外发送部分 IN高电平时&#xff0c;LED不亮&#xff0c;IN低电平时&…

飞天使-linux操作的一些技巧与知识点7-devops

文章目录 简述devopsCICD 简述devops 让技术团队&#xff0c;运维&#xff0c;测试等团队实现一体式流程自动化 进阶版图 CICD 持续集成&#xff0c; 从编译&#xff0c;测试&#xff0c;发布的完成自动化流程 持续交付&#xff0c;包含持续集成&#xff0c;并且将项目部署…

Redis集群搭建笔记

redis集群: 1.hash取余算法 2.一致性hash算法 3.哈希槽算法 以下使用哈希槽算法 Redis 3主3从搭建 新建6个Redis Docker容器实例 docker run -d --name redis-node-1 --net host --privilegedtrue -v /usr/local/develop/redis/share/redis-node-1:/data redis:6.0.8 --c…

SQL 中如何实现多表关联查询?

阅读本文之前请参阅----MySQL 数据库安装教程详解&#xff08;linux系统和windows系统&#xff09; 在SQL中&#xff0c;多表关联查询是通过使用JOIN操作来实现的&#xff0c;它允许你从两个或多个表中根据相关列的值来检索数据。以下是几种常见的JOIN类型&#xff1a; …

MFC 多文档程序的基本编程

下载了一个openGL mfc的多文档程序,以此来学习mfc多文档模式的编程; 1 基本编程 它每次新建一个文档,会在窗口绘制一个三角形、一个矩形;如果没有了图形刷新一下; 先看一下为什么每次打开新文档会绘制图形; 生成工程之后主要有5个类,比单文档程序多了一个子框架类; 可…

width:100%和width:auto有啥区别

项目中使用了with属性&#xff0c;突然好奇auto 和 100% 的区别&#xff0c;特地搜索实践总结了一下观点 一、 width属性介绍二、 代码带入三、 分析比较四、 总结 一、 width属性介绍 width 属性用于设置元素的宽度。width 默认设置内容区域的宽度&#xff0c;但如果 box-siz…

计算机组成原理 — 存储器(2)

高速缓冲存储器 大家好呀&#xff01;我是小笙&#xff0c;由于存储器这部分章节内容较多&#xff0c;我分成二部分进行总结&#xff0c;以下是第二部分&#xff0c;希望内容对你有所帮助&#xff01; 概述 目的&#xff1a;避免CPU空等现象 原理&#xff1a;程序访问的局部…

【k8s资源调度-Deployment】

1、标签和选择器 1.1 标签Label 配置文件&#xff1a;在各类资源的sepc.metadata.label 中进行配置通过kubectl 命令行创建修改标签&#xff0c;语法如下 创建临时label&#xff1a;kubectl label po <资源名称> apphello -n <命令空间&#xff08;可不加&#xff0…

IO进程:信号灯集

程序代码&#xff1a; sem.h: 1 #ifndef __SEM_H__2 #define __SEM_H__3 4 //创建信号灯集并初始化&#xff0c;semcount表示灯个数5 int open_sem(int semcount);6 7 //申请资源操作&#xff0c;semno表示灯的编号8 int P(int semid,int semno);9 10 //释放资源操作&#xff…