【数据结构】线性表

一.线性表

1.定义:

n个同类型数据元素的有限序列,记为$L=(a_1,a_2,...,a _n)$

L为表名,i为数据元素在线性表中的位序,n为线性表的表长,n=0时称为空表。

2.数据元素之间的关系:

直接前驱和直接后继

3.抽象数据类型线性表的定义:

ADT List{

数据对象:

$D=\{a_i|a_i \in ElemSet,i=1,2,...,n,n\geq 0\}$

数据关系:

$R=\{<a_{i-1},a_i|a_{i-1},a_i \in D,i=2,...,n\}$

一个长度为n的线性表有n-1个数据关系

基本操作:

(1)结构初始化操作

(2)结构销毁操作

(3)访问型操作

(4)加工型操作
}ADTList

二.存储结构

1.顺序存储

以x的存储位置和y的存储位置之间某种关系表示逻辑关系<x,y>

最简单的一种顺序存储方式是:

令y的存储位置和x的存储位置相邻。

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

线性表的起始地址称为线性表的基地址

所有数据元素的存储位置均取决于第一个数据元素的存储位置

1.1 顺序表的定位查找

将顺序表中的元素逐个与给定值e相比较

时间复杂度为$O(ListLength)$

1.2 顺序表的插入操作

插入位置以及之后的元素后移

时间复杂度为$O(ListLength)$

1.3 顺序表的删除操作

删除该元素并且该元素之后的元素前移

时间复杂度为$O(ListLength)$

2.单链表

用一组地址任意的存储单元存放线性表中的数据。

结点(表示数据元素的存储)=元素+地址

结点的序列表示线性表——称作链表

2.1 头结点

为了操作方便,在第一个结点之前虚加一个“头结点”,以指向头结点的指针为链表的头指针。

2.2 访问第i个元素

p=p->next;

时间复杂度为$O(ListLength)$

2.3 在第i个位置插入元素

寻找第i-1个位置

再进行插入

时间复杂度为$O(ListLength)$

 2.4 在第i个位置删除元素

寻找第i-1个位置

再进行删除

时间复杂度为$O(ListLength)$

2.5 将单链表置为空表

时间复杂度为$O(ListLength)$

2.6 如何从线性表中得到单链表?

链表是一个动态的结构,它不需要预先分配空间,因此生成链表的过程是一个结点“逐个插入”的过程。

2.7 其他形式的链表

1)双向链表

有两个指针,一个指向前驱,一个指向后继。

2)循环链表

最后一个结点的指针域的指针又指回第一个结点的链表。

和单链表的差别仅在于:判别链表中最后一个结点的条件不再是“后继是否为空”,而是“后继是否为头结点”。

3)双向循环链表

2.8 双向链表的操作特点

“查询”和单链表相同

“插入”和“删除”时需要同时修改两个方向上的指针。

例如“插入”:

s->next=p->next;

p->next=s;

s->next->prior=s;

s->prior=p;

例如“删除”:

s=p->next;

p->next=p->next->next;

p->next->prior=p;

delete s;

 3.总结

顺序表适合查找操作,而链表适合插入和删除操作。

三.栈(操作受限的线性数据结构)

1.栈的抽象类型定义:

ADT Stack{

数据对象:

$D=\{a_i|a_i \in ElemSet,i=1,2,3,...,n,n\geq 0\}$

数据关系:

$R1=\{<a_{i-1},a_i>|a_{i-1},a_i \in D,i=2,...,n\}$

约定$a_n$端为栈顶,$a_1$端为栈底。

基本操作:


}ADTStack

2.顺序栈

指向表尾的指针可以作为栈顶指针

3.链栈

链栈中指针的方向是从栈顶元素往下指

4.栈的应用举例:

1)数制转换

void conversion(){

    stack <int> s;

    int N;

    cin>>N;

    while(N){

        s.push(N%8);//余数进栈

        N/=8;

    }

    while(!s.empty()){

        cout<<s.top();

        s.pop();

    }

    cout<<endl;

}

2)表达式求值

表达式由操作数、运算符、界限符组成。

操作数(operand):常数或变量

运算符(operator):算数、关系、逻辑等

界限符(delimiter):左右括号、表达式结束符#等

运算符优先表

算法思想:

使用两个栈,一个运算符栈(OPTR)一个操作数栈(OPND)

1)OPND置为空栈,将#放入OPTR栈

2)依次读入表达式中的每个字符

3)若是操作数,读入OPND栈,若是运算符,则和OPTR栈的栈顶元素进行优先级比较,若栈顶元素优先级高,则执行相应运算,结果存入OPND栈;若栈顶元素优先级低,则将该字符读入OPTR栈;若优先级相同,则做‘##’或‘()’处理。

4)重复上述操作,直到表达式求值完毕(读入的是‘#’,并且OPTR栈顶元素也为‘#’)

3)迷宫求解

回溯法:一种不断试探且及时纠正错误的搜索方法。

回溯法思想:从入口出发,按某一方向向前探索,若能走通(未走过),则到达新点,否则试探下一没有探索过的方向,若所有的方向均没有通路,则沿原点返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索过,或找到一条通路,或无路可走又返回到入口点。

(1)表示迷宫的数据结构

#define M 6        //迷宫的实际行和列

#define N 8

int maze[M+2][N+2];

入口坐标为(1,1),出口坐标为(M,N)

(2)试探方向

每个点有8个方向可以试探,试探顺序规定为:从正东方向顺时针方向进行。

move数组定义

typedef struct{
int x,y;

}item;

item move[8];

x:行坐标增量

y:列坐标增量

(3)栈的设计

当到达了某点而无路可走时需要返回前一点,再从前一点开始向下一个方向继续试探。因此,压入栈中的不仅是顺序到达的各点的坐标,而且还要有从看一点到达本点的方向。

栈中元素是一个由行、列、方向组成的三元组。

typedef struct{
int x,y,direction;

}datatype;

栈的定义为:

stack <datatype> s;

(4)如何防止重复到达某点,以避免发生死循环?

当到达某点(i,j)时,将maze[i][j]置为-1

(5)迷宫求解算法思想

1.栈初始化

2.将入口点坐标以及到达该点的方向direction设置为-1,入栈。

3.while(栈不为空)

{

弹栈

求出下一个要试探的方向direction++

while(还有剩余试探方向时){

if(direction方向可走){

则{x,y,direction}入栈,求新点坐标(i,j)

将新点(i,j)切换为当前点(x,y)

if((x,y)==(M,N)){

结束

                }

else{

重制direction=0;

}

}

else

direction++;

}

}

四.队列

1.队列的抽象定义

ADT Queue{

数据对象:

$D=\{a_i|a_i \in ElemSet,i=1,2,...,n,n\geq 0\}$

数据关系:

$R1=\{<a_{i-1},a_i>|a_{i-1},a_i \in D,i=2,...,n\}$

约定:其中$a_1$端为队列头,$a_n$端为队列尾。

基本操作:


}ADT Queue

2.顺序队列

#define MAXQSIZE 100
typedef struct{
ElemType base[MAXQSIZE];
int front;//头指针,若队列不为空,指向队列头元素
int resr;//尾指针,若队列不为空,指向队列尾元素的下一个位置
}SqQueue;

2.1 "假溢出"

为了解决假溢出问题,采用循环队列

队满和队空时均有sq.front==sq.rear

无法判断队满还是队空。

1)方法一:

用一个计数变量来记录队列中元素的个数。

2)方法二:

设置一个标志位。

当有元素入队时,标志位为true;有元素出队时,标志位为false。

3)方法三:

牺牲一个元素空间,来区别队空或队满。 

队满:(sq.rear+1)%queue_length==sq.front

队空:sq.front==sq.rear

2.2 插入元素e为Q的新的队尾元素

1)判断队列是否满

2)满了,则error

3)没满,Q.base[Q.rear]=e;

Q.rear=(Q.rear+1)%queue_length;

2.3 出队

1)判断队列是否为空

2)空,返回error

3)非空,e=Q.base[Q.front];

Q.front=(Q.front+1)%queue_length;

2.4 队列长度 

return ((Q.rear-Q.front+queue_length)%queue_length);

3.链队列

typedef struct QNode{
QelemType data;
struct QNode *next;}*QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;

3.1 插入元素e为Q的队尾元素

p=new QNode;

p->data=e;

p->next=NULL;

Q.rear->next=p;

Q.rear=p; 

3.2 出队

if(Q.front==Q.rear)

        return error;

p=Q.front->next;

e=p->data;

Q.front->next=p->next;

if(Q.rear==p)

        Q.rear=Q.front;//避免尾指针成为野指针

delete p;

3.3 构造函数

Q.front=Q.rear=new QNode;

Q.front->next=NULL;//带头结点

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

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

相关文章

git首次使用--去公司第一次拉取

文章目录 一&#xff0c; 在企业中首次拉取项目二&#xff0c;提交项目1. 提交----新添加的文件2. 将分支上的代码同步到master3. 提交----更改后的文件 三&#xff0c;常见问题1. Git Pull Failed 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一&am…

固定效应模型-以stata为工具

固定效应模型-以stata为工具 文章目录 1.固定效应模型2. 模型原理3. `stata`代码实现1.固定效应模型 固定效应模型(Fixed Effects Model)是一种面板数据分析方法,通过引入个体固定效应来控制个体间的异质性,并更准确地估计解释变量对因变量的影响。它在许多经济、社会科学…

qt项目-《图像标注软件》源码阅读笔记-类图

目录 1. 开源项目链接 2. 项目界面 3. 项目类图 3.1 形状的绘制及形状的存储 3.2 主窗口中心组件的界面管理 3.3 Command负责实现撤销和重做功能 3.4 其他类 3.5 枚举 3.5.1 Status 主窗口的状态变量 3.5.2 Mode 主窗口模式状态变量 3.5.3 shapeStatus 中心组件状态…

josef约瑟 电流继电器 RL-D1 电压AC220V 整定范围0-9.99AAC

系列型号 RL-D1型电流继电器&#xff1b; RL-D2型电流继电器&#xff1b; 基本参数 RL-D系列电流继电器用于发电机、变压器和输电线的过负荷和短路保护装置中作为启动元件。本继电器为集成电路型继电器&#xff0c;精度高、功耗小、动作时间快&#xff0c; 返回系数高、整定…

AndroidStudio无法新建aidl文件解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 右键新建 aidl 文件&#xff0c; 提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file 解决办法 修改 app 的 build.…

03_排序

03_排序 一、简单排序Comparable接口介绍需求&#xff1a; 冒泡排序排序原理&#xff1a;冒泡排序API设计&#xff1a; 选择排序排序原理&#xff1a;选择排序API设计&#xff1a;选择排序的时间复杂度分析&#xff1a; 插入排序需求&#xff1a;排序原理&#xff1a;插入排序A…

三菱人机交互GT Designer的安装

今天&#xff0c;与小编一起来学习三菱的GT Designer软件&#xff0c;下面就是小编记录的软件查找&#xff0c;安装的全过程&#xff0c;希望对你学习三菱有帮助。 目录 安装 选择官网下载安装包 解压安装包进行安装 创建一个工程 安装 选择官网下载安装包 三菱&#xff08;中…

如何在linux安装软件

一.安装种类 1.编译安装&#xff1a;灵活性高&#xff0c;难度较大&#xff0c; 可以安装新版本 2.rpm安装&#xff1a;查软件信息&#xff0c;是否安装&#xff0c;文件列表 3.yum&#xff1a;是rpm的升级版本&#xff0c;解决rpm的弊端 rpm安装&#xff1a; 安装软件的时…

【架构】ServerLess

文章目录 概述什么是serverless无服务与传统模式架构区别serverless优缺点使用serverless的应用场景有哪些“无服务器”搭建网站Serverless的落地案例来源 概述 架构 单体&#xff08;三层架构&#xff09;微服务分布式ServerLess 什么是serverless无服务 serverless中文的…

VirtualBox虚拟机使用USB3.0网卡与开发板通信

因为我的笔记本没有带网口&#xff0c;所以我使用的是USB网卡。我按照网上其他人发的“VirtualBox与开发板、主机相互ping通”文章中提到的方法&#xff0c;进行网络设置后发现仍然无法实现Ubuntu虚拟机与主机和Linux开发板相互ping通。 仔细回想以前Ubuntu虚拟机使用USB读卡器…

Docker - 镜像 | 容器 日常开发常用指令 + 演示(一文通关)

目录 Docker 开发常用指令汇总 辅助命令 docker version docker info docker --help 镜像命令 查看镜像信息 下载镜像 搜索镜像 删除镜像 容器命令 查看运行中的容器 运行容器 停止、启动、重启、暂停、恢复容器 杀死容器 删除容器 查看容器日志 进入容器内部…

SpringSecurity【3】之授权

继续昨天的认证&#xff0c;今天来分析 在Spring Security中&#xff0c;授权是指对用户访问系统资源的限制。Spring Security提供了多种授权方式&#xff0c;包括基于角色的授权、基于表达式的授权、注解授权等。 基于角色的授权是指通过为用户分配不同的角色来限制其访问系统…

四、UART_阻塞发送中断接收

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)MCU: mm320163D7P 2、实验目的&原理图 2.1、实验目的 (1)上位机串口助手给MCU发送信息&#xff0c;MCU串口通过通过串口助手接收后&#xff0c;将接收到的内容通过串口助手发送到上位机。 (2)串口在whil循环中每隔1秒发送一次…

蓝桥杯2020年5月青少组Python程序设计国赛真题

1、 上边是一个算法流程图,最后输出的b的值是() A.377 B.987 C.1597 D.2584 2、 3、如果整个整数X本身是完全平方数,同时它的每一位数字也都是完全平方数我们就称X 是完美平方数。前几个完美平方数是0、1、4、9、49、100、144......即第1个完美平方数是0,第2个是 1,第3个…

Hadoop入门学习笔记——一、VMware准备Linux虚拟机

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 一、VMware准备Linux虚拟机1.1. VMware安装Linux虚拟机1.…

WEB 3D技术 three.js 通过lil-gui 控制x y z轴数值 操作分组 设置布尔值控制 颜色材质控制

上文 WEB 3D技术 three.js 通过lil-gui管理公共事件中 我们用 lil-gui 处理了一下基础事件和按钮的管理 那么 本文 我们来具体说说它能做的其他事 我们先将基础代码改成这样 import ./style.css import * as THREE from "three"; //引入lil-gui import { GUI } fro…

安装Kubernetes1.23、kubesphere3.4、若依项目自动打包部署到K8S记录

1.安装kubernetes1.23详细教程 kubernetes(k8s)集群超级详细超全安装部署手册 - 知乎 2.安装rancher动态存储 kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml3.安装kubesphere3.4 准备工作 您…

UE和Android互相调用

ue和android互调 这两种方式都是在UE打包的Android工程之上进行的。 一、首先是UE打包Android&#xff0c;勾选下面这项 如果有多个场景需要添加场景 工程文件在这个路径下 然后可以通过Android Studio打开&#xff0c;选择gradle打开 先运行一下&#xff0c;看看是否可以发布…

032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识

032 - STM32学习笔记 - TIM定时器&#xff08;一&#xff09; - 基本定时器知识 这节开始学习一下TIM定时器功能&#xff0c;从字面意思上理解&#xff0c;定时器的基本功能就是用来定时&#xff0c;与定时器相结合&#xff0c;可以实现一些周期性的数据发送、采集等功能&#…

DMR与DPMR以及DMR的分层

数字移动无线电 (DMR) 和数字专用移动无线电 (dPMR) 是数字对讲机中使用的流行通信技术。 与传统模拟无线电相比&#xff0c;这两种技术都提供了改进的音频质量、增强的安全功能和增加的网络容量。 但是&#xff0c;DMR 和 dPMR 无线电之间使用的技术存在重大差异&#xff…