【数据结构1-1】线性表

news2024/11/24 14:26:54

线性表是最简单、最基本的一种数据结构,线性表示多个具有相同类型数据“串在一起”,每个元素有前驱(前一个元素)和后继(后一个元素)。根据不同的特性,线性表也分为数组(vector)、栈(stack)、队列(queue)、链表(list)等等。根据这些特性和数据结构可以解决不同种类的问题。

 一、寄包柜(vector or map)

 1.1 使用vector

vector和数组相比,vector可以改变长度,清空的时间复杂度为O(1)。

vector常用操作如下: 


AC代码:

我们可以建立一个二维数组s[x][y]来记录第i个柜子的第j个格子中的物品。根据本题的数据范围,需要开一个大约40GB的int数组,而本题的空间限制这有125MB,显然会超空间,所以我们可以用一个vector来解决。

先设定一个可以满足大多数情况且不超内存的二维可变数组,如果实际情况所需内存超过所开范围可以使用resize函数重新为vector分配空间。

#include <bits/stdc++.h> //头文件
using namespace std;
inline int read() //快读
{
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
inline void write(int x) //快出
{
    if(x<0)
	{
    	putchar('-');
		x=-x;
	}
    if(x>9)
		write(x/10);
    putchar(x%10+'0');
}
int main() //主函数
{
	ios::sync_with_stdio(false); //输入输出优化流
	int n,q,f,x,y,z; //定义
	n=read(); //输入寄包裹个数和询问次数
	q=read();
	vector<vector<int> > a(n+1); //定义一个可变数组,初始化,总共0-n号寄包柜
	while(q--)
	{
		f=read(); //输入操作种类
		if(f==1) //存包操作
		{
			x=read(); //输入
			y=read();
			z=read();
			if(a[x].size()<y+1) a[x].resize(y+1); //如果这个寄包柜不够大,就扩大新的寄包柜,直到能装下为止
			a[x][y]=z; //存包
		}else{
			x=read(); //输入
			y=read();
			write(a[x][y]); //输出下标为x,y的元素
			puts(""); //换行
		}
	}
	return 0; //结束
}

使用可变长度数组vector的方法可以使得二维数组中每一行的长度不一样,从而在一定程度上减少空闲空间的产生,不过这种方法有一定局限性。 


1.2 使用map

显然使用vector并不是最优写法,因为只有少量数组空间会被利用,大量空间会被浪费,这里我们可以想到使用离散化的方式来对稀疏数据进行操作,即使用map。

map常用操作如下:

AC代码:

由于本题中有柜号和格子号二维信息,所以使用map容器嵌套pair类型变量即可,不需要开辟二维map。

使用count函数可以实现对map中键值的存在性查找。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

map<pair<long, long>, long> bag;

int main()
{
	int n, q;
	cin >> n >> q;
	for (int i = 1; i <= q; i++)
	{
		int type = 0;
		cin >> type;
		if (type == 1)
		{
			int x, y, k;
			cin >> x >> y >> k;
			bag[{x, y}] = k;
		}
		else if (type == 2)
		{
			int x, y;
			cin >> x >> y;
			if (bag.count({ x,y }) != 0)
			{
				cout << bag[{x, y}] << endl;
			}
		}
	}
}

二、队列安排(list)

list是一种实际运用比较少的数据类型,一般可以使用vector来代替,list的优势在于可以快速的插入和删除链上元素,劣势在于只能使用迭代器进行顺序查找。 

list使用方法: 

AC代码:

 本题将每个同学看作一个节点,使用链表将其连接在一起。但由于list查找速度缓慢,同时随机插入节点会导致list中节点的编号混乱,为了减少遍历list查找节点浪费的时间,我们可以使用一个数组来顺序保存每一个节点的迭代器。从而实现O(1)量级的快速查找。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <list>

using namespace std;
using Iter = list<int>::iterator;

const int maxN = 1e5 + 5;
list<int> List;
Iter pos[maxN];
bool be[maxN] = { false };

int main()
{
	int N, M;
	cin >> N;
	List.push_front(1);
	pos[1] = List.begin();

	for (int i = 2; i <= N; i++)
	{
		int k, p;
		cin >> k >> p;
		if (p == 0)
		{
			pos[i] = List.insert(pos[k], i);
		}
		else
		{
			pos[i] = List.insert(next(pos[k]), i);
		}
	}
	cin >> M;
	for (int i = 1; i <= M; i++)
	{
		int tmp;	cin >> tmp;
		if (tmp <= N && !be[tmp])
		{
			List.erase(pos[tmp]);
			be[tmp] = true;
		}
	}
	for (auto x : List)
	{
		cout << x << " ";
	}
}

 list中的迭代器为list<int>::iterator,使用数组pos按照1~n顺序保存每个节点所在list中的位置。同时由于删除节点会耗费一定的时间,我们可以使用一个辅助数组be来保存list中每个节点的存在性,be数组与list节点一一对应。


三、验证栈序列(stack) 

栈是唯一的只能从一个开口增删数据的数据结构,使用push函数向栈中压入数据,使用pop弹出数据,使用top函数查看栈顶数据。

需要注意的是如果栈为空,仍然使用top函数会异常中断,报错。

stack使用方法:

AC代码:

本题使用栈对序列进行模拟。将pushed中数据依次入栈,当栈顶数与poped序列中某数相同时,将栈顶数出栈。若操作结束后,栈中仍然有残留数据,说明poped序列无法实现。

#include <iostream>
#include <string>
#include <algorithm>
#include <stack>

using namespace std;

int pushed[100005];
int poped[100005];
stack<int> stk;
int main()
{
	int q;	cin >> q;
	for (int cnt = 1; cnt <= q; cnt++)
	{
		int num;	cin >> num;
		for (int i = 1; i <= num; i++)
			cin >> pushed[i];
		for (int i = 1; i <= num; i++)
			cin >> poped[i];
		int index = 1;
		for (int i = 1; i <= num; i++)
		{
			stk.push(pushed[i]);
			while (stk.top() == poped[index])
			{
				stk.pop();
				index++;
				if (stk.empty())
					break;
			}
		}
		if (stk.empty()) cout << "Yes" << endl;
		else cout << "No" << endl;
		while (!stk.empty())
			stk.pop();
	}
}

本题中存在的坑在于当栈为空时,使用top函数会报错,需先用empty函数确认栈不为空后,才能使用top函数查看栈顶。 


四、海港(queue) 

queue(队列)为两端开口,的管道容器,一侧为入口,一侧为出口,可以实现先进先出,后进后出,无法随机增删,此外还有deque(双端队列),管道两侧均可以增删数据。

queue使用方法:

 AC代码:

本题可以将node结构塞入queue队列当中,node结构中存储某个人的信息,包括下船时间和国籍,由于下船时间已经从下到大排序,所以每次淘汰下船时间超过24h的人时只需要从出口端删除信息即可。

#include <iostream>
#include <string>
#include <algorithm>
#include <queue>

using namespace std;

struct node
{
	int Time;
	int Nation;
};
queue<node> ship;
int national[100005] = { 0 };

int main()
{
	int n;	cin >> n;
	int count = 0;
	for (int cnt = 1; cnt <= n; cnt++)
	{
		int t, k;
		cin >> t >> k;
		while (!ship.empty())
		{
			if (t - ship.front().Time >= 86400)
			{
				national[ship.front().Nation] -= 1;
				if (national[ship.front().Nation] == 0)
				{
					count -= 1;
				}
				ship.pop();
			}
			else
				break;
		}
		for (int i = 1; i <= k; i++)
		{
			int people; cin >> people;
			node tmp;
			tmp.Time = t, tmp.Nation = people;
			ship.push(tmp);
			if (national[tmp.Nation] == 0)
				count += 1;
			national[tmp.Nation] += 1;
		}
		printf("%d\n", count);
	}
	
}

代码逻辑为:

  1. 先淘汰下船时间超过24h的人,用一个national数组存储每个国籍的人数,若淘汰后某个国籍人数为0,那么count减1;
  2. 然后对当前时间下船的人操作,若该人的到来使得某个国籍的人数从0变为1,那么count加1.

五、营业额统计(set)

set能有序地维护同一类型的元素,但相同的元素只能出现一次。

也就是说,我们将数据插入set中后,set会自动帮我们排序(相当于优先队列)。

set使用方法:

AC代码: 

每次输入一个新的数x后,通过lowerbound操作找到set中大于等于x的第一个数。

  • 如果这是第一个数,直接插入到set里。
  • 这个数等于x,显然最小波动值为0,我们也不需要再插入一个x放到set里了。
  • 这个数大于x,通过set的特性可以很轻松的找到这个数的前驱,也就是小于x的第一个数。将两个数分别减去x,对绝对值取个min就好了。此时要将x插入到set中。
#include <iostream>
#include <string>
#include <algorithm>
#include <set>

using namespace std;

set<int> s;
set<int>::iterator r,l;
int main()
{
	int n;	cin >> n;
	int a;	cin >> a;
	s.insert(a);
	int ans = a;
	for (int i = 2; i <= n; i++)
	{
		int tmp;		cin >> tmp;
		r = s.lower_bound(tmp);
		if (r == s.end())
		{
			ans += abs(tmp - *(--r));//k的前一个数,也就是小于tmp的最大数
			s.insert(tmp);
			continue;
		}
		else if (r == s.begin())
		{
			ans += abs(tmp - *r);
			s.insert(tmp);
			continue;
		}
		else
		{
			l = --s.lower_bound(tmp);
			ans += min(abs(tmp - *r), abs(tmp - *l));
			s.insert(tmp);
		}
	}
	cout << ans;
}

迭代器是一种检查容器内元素并遍历元素的数据类型,通常用于对C++中各种容器内元素的访问,但不同的容器有不同的迭代器,初学者可以将迭代器理解为指针

 迭代器使用方法:

  • 比较两个迭代器是否相等(==、!=)。
  • 前置和后置递增运算(++、--)(无法随机访问!)。
  • 读取元素的解引用运算符(*)。只能读元素,也就是解引用只能出现在赋值运算符的右边。
  • 箭头运算符(->),解引用迭代器,并提取对象的成员。

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

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

相关文章

JVM基础知识汇总篇

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

【Docker】附录二:热门镜像介绍

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 热门镜像介绍 本章将介绍一些热门镜像的功能&#xff0c;使用方法等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、No…

k8s学习-DaemonSet和Job

1.1DaemonSet是什么 Deployment部署的副本Pod会分布在各个Node上&#xff0c;每个Node都可能运行好几个副本。DaemonSet的不同之处在于&#xff1a;每个Node上最多只能运行⼀个副本。DaemonSet的典型应用场景有&#xff1a; &#xff08;1&#xff09;在集群的每个节点上运⾏存…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-38203)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞,该漏洞源于受到不受信任数据反序列化漏洞的影响,攻击者通过漏洞可以代码执行,可导致服务器失…

6.小时表天分区和小时分区顺序错误,怎么办?

目录 一、解决思路二、修复表结构2.1 建表2.2查询数据2.3查询数据路径2.4删表重建2.5查询表结构2.6查询数据 三、恢复数据3.1方案1 直接移动原分区数据到新分区下3.2方案2 将分区路径指导原数据路径3.3方案3 通过临时表恢复数据 一、解决思路 对于这个问题&#xff0c;主要分为…

C++类和对象——构造函数与解析函数介绍

目录 1.构造函数和析构函数 1.构造函数&#xff0c;进行初始化 2.析构函数&#xff0c;进行清理 2.构造函数的分类及调用 1.括号法 注意&#xff1a; 2.显示法 3.隐式转化法 匿名对象 3.拷贝构造函数调用时机 4.构造函数调用规则 1.定义有参构造函数&#xff0c;不…

微信小程序之页面导航、生命周期和WXS脚本

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

机器学习的数据库积累........

https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md ​​​​​​​ 另一个database:&#xff08;网址:Object Detection Made Easy with TensorFlow Hub: Tutorial&#xff09; Object Detection Made Easy with Ten…

【Java Kubernates】Java调用kubernates提交Yaml到SparkOperator

背景 目前查询框架使用的是trino&#xff0c;但是trino也有其局限性&#xff0c;需要准备一个备用的查询框架。考虑使用spark&#xff0c;spark operator也已经部署到k8s&#xff0c;现在需要定向提交spark sql到k8s的sparkoperator上&#xff0c;使用k8s资源执行sql。 对比 …

RCC——使用HSE/HSI配置时钟

RCC 文章目录 前言一、背景二、仿真计算周期 2.1 2.2 三、MCO引脚输出时钟总结 前言 前期疑问&#xff1a;1、RCC是什么意思。 2、最终配好的72M是系统时钟吗&#xff1f; 3、一共有哪些时钟 本文目标&#xff1a;将PLL时钟配置成72M 疑问解答&#xff1a;最终配好的时钟是…

GitLab16.8配置webhooks、Jenkins2.4配置GitLab插件实现持续集成

看本篇文章的前提是已经部署完GItlab和Jenkins服务器&#xff0c;已经可以手动构建成功&#xff0c;并且经过了很多次实践&#xff0c;对这两款软件基本熟悉。 希望大家都能够厚积薄发。 ~~~道理都懂&#xff0c;但有时候做不到&#xff0c;所以还是没真正懂。 前端自动化&am…

【Qt无门槛入门】信号以及信号机制及其常用控件(1)

信号与信号槽 信号源&#xff1a;由哪个控件发出的信号。 信号的类型&#xff1a;用户进行不同的操作&#xff0c;就可能出发不同的信号。 信号处理的方式:槽&#xff08;slot&#xff09;某个对象接收到这个信号之后&#xff0c;就会做一些相关的处理动作。但是Qt对象不会无故…

uniCloud 免费版和商用版

概述 uniCloud为每个开发者提供一个免费的服务空间&#xff0c;更低门槛按量付费是serverless的特色&#xff0c;如果没有消耗硬件资源&#xff0c;就完全不用付款serverless比传统的云主机更便宜传统云主机一旦被攻击&#xff0c;高防价格非常昂贵。而uniCloud无需支付高防费…

零基础学习数学建模——(五)美赛写作指导

本篇博客将详细讲解美赛论文写作。 文章目录 标题摘要目录引言问题背景问题重述前人研究我们的工作 模型假设及符号说明正文问题分析模型建立模型求解结果分析模型检验 模型优缺点及展望模型优缺点模型展望 参考文献及附录参考文献附录 2024年美赛论文新要求 标题 标题要简洁…

Linux使用二进制包安装MySQL

目录 一、软件包下载 二、上传软件包到Linux根目录 1、使用xftp将软件包上传到根目录 2、解压缩 三、准备工作 四、初始化软件 五、设置MySQL的配置文件 六、配置启动脚本 一、软件包下载 官网下载&#xff1a;MySQL :: Download MySQL Community Server 二、上传软件…

Future模式先给您提货单

Future模式是一种设计模式&#xff0c;用于在处理耗时操作时提高程序的响应性。 角色介绍: Main类: 负责向Host发出请求并获取数据的类。 Host类: 负责向请求返回FutureData的实例的类&#xff0c;起到调度的作用。 Data接口: 表示访问数据的方法的接口&#xff0c;由FutureD…

LabVIEW电液比例阀测试系统

电液比例阀与普通阀和伺服阀相比&#xff0c;比例阀展现出显著的耐污染和可靠性特点。为了满足这些比例阀的综合性能测试需求&#xff0c;开发了一种基于LabVIEW软件的电液比例阀综合性能试验台。这个系统不仅能够进行比例压力阀、流量阀和方向阀的性能测试&#xff0c;而且通过…

STM32-LwESP 移植

LwESP 是一个专门解析 Espressif 公司旗下 ESP 系列芯片 AT 指令的开源库&#xff0c;具有以下特性&#xff1a; 支持 Espressif 公司 ESP32, ESP32-C2, ESP32-C3, ESP32-C6 和 ESP8266 芯片。独立平台&#xff0c;采用 C99 标准编写&#xff0c;易于移植。允许不同的配置来优…

前端大厂面试题探索编辑部——第二期

目录 题目 单选题1 题解 关于TCP 关于UDP 单选题2 题解 A选项的HTTP是否是无状态协议 B选项的HTTP支持的方法 C选项的关于HTTP的状态码 D选项HTTP协议的传输格式 题目 单选题1 1.以下哪个描述是关于 TCP 和 UDP 的区别&#xff08;&#xff09; A. TCP 是无连接的…

大创项目推荐 题目:基于python的验证码识别 - 机器视觉 验证码识别

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