用数组模拟单链表、双链表、栈、单调栈、队列、循环队列、单调队列

本文用于记录个人算法竞赛学习,仅供参考

目录

一.模拟单链表

二.双链表

三.栈

四.单调栈

五.队列

六.循环队列

七.单调队列


为什么要用数组模拟而不用现成的STL,因为用数组模拟效率会快一点,比如用结构体+指针的方式创建链表,new的效率会很慢,极端情况可能会超时,所以有时候需要用数组模拟。

一.模拟单链表

用数组模拟单链表,需要两个数组,一个数据域,一个指针域;head记录链表的起始位置;index用于记录当前已经用到哪个点(用于创建节点),index一直向后走,不会走回头路,这里的index相当于每个节点的地址,每个节点的地址都独一无的。

 模板:

//head 存储链表头节点   e[] 存储节点的值   ne[] 存储节点的next指针
//index 记录当前已经用到了哪个节点,相当于地址,用于创建节点

const int N = 100010;//看情况给大小
int head, e[N], ne[N], index;

//初始化
void init()
{
	head = -1;//表示空集
	index = 0;
}
//在链表头插入一个数a--相当于创建一个数据为a的节点头插链表
void insert(int a)
{
	e[index] = a;
	ne[index] = head;
	head = index++;//记得index要向后走
}
//头删
void remove()
{
	//不存在节点
	if (head == -1)
		return;
	head = ne[head];
}
//插到下标k后面//如果向插到下标k前面
void insert_k(int k, int a)
{
	e[index] = a;
	ne[index] = ne[k];
	ne[k] = index++;
}
//将下标k后面的点删除
void remove_k(int k)
{
	ne[k] = ne[ne[k]];
}
//遍历
void ergodic()
{
	for (int i = head; i != -1; i = ne[i])
		cout << e[i] << ' ';
}

二.双链表

双链表比单链表多了一个指针域

模板:

// e[] 存储节点的值   l[] 存储节点的pre指针   r[]存放节点的next指针
//index 记录当前已经用到了哪个节点,相当于地址,用于创建节点

const int N = 100010;//看情况给大小
int e[N], l[N], r[N], index;

//初始化
void init()
{
	//0是head指针,1是tail指针, 0头节点右指针指向1尾节点,1尾节点的左指针指向0头节点,形成闭环
	r[0] = 1, l[1] = 0;
	index = 2;//要从2开始了
}
//在节点k右边插入一个数a//在k左边插入一个数a 即为 insert(l[k], a);
void insert(int k, int a)
{
	e[index] = a;
	l[index] = k;
	r[index] = r[k];
	l[r[k]] = index;
	r[k] = index++;
}
//删除节点k
void remove(int k)
{
	l[r[k]] = l[k];
	r[l[k]] = r[k];
}

三.栈

栈是先进后出的数据结构,只需要维护栈顶就可以了

模板:

const int N = 100010;
//栈
int st[N];
//tt维护栈顶,tt == 0时是栈底,栈底不存数据
int tt = 0;

//插入
void insert(int a)
{
	st[++tt] = a;
}
//删除
void remove()
{
	tt--;
}
//栈顶数值
int top()
{
	return st[tt];
}
//判空
bool empty()
{
	if (tt == 0)
		return true;//空
	else
		return false;//不为空
}

四.单调栈

单调栈(Monotonic Stack)是一种数据结构,用于解决一类特定的问题,通常用于求解数组中元素的下一个更大元素、前一个更大元素等问题。

单调栈的特点是栈内元素保持单调递增或单调递减。具体来说,对于单调递增栈,栈内元素从栈底到栈顶是递增的;对于单调递减栈,栈内元素从栈底到栈顶是递减的。

在使用单调栈解决问题时,通常会遍历数组元素,维护一个单调栈,根据具体问题的要求,不断更新栈内元素,以得到需要的结果。

模板:

int tt = 0;
//伪代码,具体看题目
for (int i = 1; i <= n; i++)
{
	//check是处理逻辑,满足条件就出栈
	while (tt && check(st[tt], i))
	{
		tt--;
	}
	st[++tt] = i;
}

 496. 下一个更大元素 I - 力扣(LeetCode)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        //单调栈--map
        vector<int> ans(nums1.size(), -1);
        if(nums1.size() == 0)   return ans;
        stack<int> st;
        st.push(0);
        //map哈希映射
        unordered_map<int,int> umap;
        for(int i = 0; i < nums1.size(); i++)
        {
            umap[nums1[i]] = i;
        }
        for(int i = 1; i < nums2.size(); i++)
        {
            if(nums2[i] > nums2[st.top()])
            {
                while(!st.empty() && nums2[i] > nums2[st.top()])
                {
                    if(umap.count(nums2[st.top()]) > 0)
                    {
                        ans[umap[nums2[st.top()]]] = nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
            else
            {
                st.push(i);
            }
        }
        return ans;
    }
};

五.队列

维护对头和队尾

const int N = 100010;
//队列
int q[N];
//对头,队尾
int hh = 0, tt = -1;

//向队尾插入一个数
void insert(int a)
{
	q[++tt] = a;
}
//从队头弹出一个数
void pop()
{
	hh++;
}
//返回队头的值
int front()
{
	return q[hh];
}
//判空
bool empty()
{
	if (hh <= tt)
		return false;//不为空
	else
		return true;
}

六.循环队列

也就多了个循环,队列满时直接改个方向

//hh表示队头,tt表示队尾的后一个位置
const int N = 100010;
int q[N];
int hh = 0, tt = 0;

//向队尾插入一个元素
void insert(int a)
{
	q[tt++] = a;
	//队满,循环改向
	if (tt == N)
		tt = 0;
}
//从队头弹出一个元素
void pop()
{
	hh++;
	if (hh == N)
		hh = 0;
}
//返回队头的值
int front()
{
	return q[hh];
}
//判空
bool empty()
{
	if (hh == tt)
		return true;//空
	else
		return false;//不为空
}

七.单调队列

单调队列(Monotonic Queue)是一种数据结构,通常用于解决一些需要维护一组数据中的最大值或最小值的问题(比如滑动窗口中的最大值和最小值)。单调队列可以支持在队列两端进行插入和删除操作,并且保持队列中的元素是单调递增或单调递减的。

单调队列的主要特点是在插入元素时,会将比当前元素小的元素从队列尾部删除,以保持队列的单调性质。这样可以确保队列头部始终是当前队列中的最大值或最小值。

在实际应用中,单调队列常用于求滑动窗口中的最大值或最小值等问题,可以在O(N)的时间复杂度内解决这类问题。

单调队列的基本操作包括:
1. 在队尾插入元素,并保持队列的单调性;
2. 在队头删除元素;
3. 获取队列的头部元素(最大值或最小值)。

单调队列可以通过双端队列(Deque)来实现,具体实现方式可以根据具体问题的需求选择单调递增队列或单调递减队列。

接下来用数组来模拟实现单调队列:

模板:

const int N = 100010;
//队列
int q[N];
//队头,队尾
int hh = 0, tt = -1;

//伪代码
for (int i = 0; i < n; i++)
{
	//队头是否滑出窗口
	while (hh <= tt && check_out(q[hh]))
		hh++;
	//入队列要保持单调
	while (hh <= t && check(q[tt], i))
		tt--;
	q[++tt] = i;
}

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

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

相关文章

C++ 二叉树OJ题

&#x1f493;博主CSDN主页:麻辣韭菜-CSDN博客&#x1f493;   ⏩专栏分类&#xff1a;C知识分享⏪   &#x1f69a;代码仓库:C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; 前言 C二叉搜索树 这篇讲解了搜索二叉…

动态规划1

动态规划问题的五步操作&#xff1a; 动态规划就是把dp表填满&#xff0c;则最终一定有一个数据是我们所需要的数据 下面以一道简单的题目进行讲解 本题其实就是斐波那契数列的一个plus版 &#xff0c;就是利用递推关系求值的过程 1.前期准备&#xff1a;创建dp表(使用一维…

GRE和MGRE

思维导图 综合实验 配置IP地址 R1&#xff1a; [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 192.168.1.1 24 [R1-GigabitEthernet0/0/0]int s3/0/0 [R1-Serial3/0/0]ip add 15.1.1.1 24 R2: [R2]int g 0/0/0 [R2-GigabitEthernet0/0/0]ip ad 192.168.2.2 24 [R2-G…

基于四足机器人和机械臂的运动控制系统(二)

文章目录 前言一、四足步态二、视觉抓取三、远程遥控 谢绝转载&#xff0c;无作者许可不可用做其他用途&#xff08;如教育展示产品、课程设计或毕业设计等&#xff09; 前言 衔接上一篇文章&#xff0c;这篇文章主要来介绍项目的初步实现 一、四足步态 可以知道&#xff0…

常用的几种排序算法小结

目录 1.冒泡排序 2.堆排序 2.1堆的基础知识和特性 2.2向上调整算法和向下调整算法 2.3堆排序实现 3.插入排序 4.希尔排序 5.选择排序 5.1选择排序递归版 5.2选择排序非递归版 6.快速排序 6.1 Hoare版本之递归 6.1.1普通版 6.1.2随机数版 6.1.3三数取中版 6.1.4小区间优化…

前端虚拟滚动列表 vue虚拟列表

前端虚拟滚动列表 在大型的企业级项目中经常要渲染大量的数据&#xff0c;这种长列表是一个很普遍的场景&#xff0c;当列表内容越来越多就会导致页面滑动卡顿、白屏、数据渲染较慢的问题&#xff1b;大数据量列表性能优化&#xff0c;减少真实dom的渲染 看图&#xff1a;绿色…

安装最新的wxPython和Python3并保证二者兼容

要安装最新的wxPython和Python3并保证二者兼容&#xff0c;你可以按照以下步骤进行操作&#xff1a; 安装Python3&#xff1a; 访问Python官方网站下载适合你操作系统的最新版Python3安装包。运行安装程序&#xff0c;确保在安装过程中将Python添加到系统环境变量中。安装完成…

【Java】:static成员和代码块

目录 1.static成员 1.1再谈学生类 1.2static修饰成员变量 1.3static修饰成员方法 1.4static成员变量初始化 1.4.1就地初始化 1.4.2静态代码块初始化 2.代码块 2.1代码块概念以及分类 2.2普通代码块 2.3构造代码块 2.4静态代码块 1.static成员 1.1再谈学生类 使用类…

MATLAB 点云随机渲染赋色(51)

MATLAB 点云随机渲染赋色(51) 一、算法介绍二、算法实现1.代码2.效果总结一、算法介绍 为点云中的每个点随机赋予一种颜色,步骤和效果如图: 1、读取点云 (ply格式) 2、随机为每个点的RGB颜色字段赋值 3、保存结果 (ply格式) 二、算法实现 1.代码 代码如下(示例):…

gin基础学习笔记--参数验证

用gin框架的数据验证&#xff0c;可以不用解析数据&#xff0c;减少if else&#xff0c;会简洁许多。 package mainimport ("fmt""time""github.com/gin-gonic/gin""github.com/gorilla/sessions" )// 初始化一个cookie存储对象 // s…

基于STM32的武警哨位联动报警系统设计,支持以太网和WIFI通信

1.功能 本文提出的武警报警信息系统终端&#xff0c;可实现报警和联动响应&#xff0c;支持以太网和WIFI两种通信模式&#xff0c;可实现移动哨位报警和固定哨位报警&#xff0c;语音和显示报警信息用户可自行定制。 本终端主要由STM32F103处理器模块和C8051F340处理器模块构…

P-MapNet:Far-seeing Map Generator Enhanced by both SDMap and HDMap Priors

主页&#xff1a;homepage 参考代码&#xff1a;P-MapNet 动机与出发点 在感知系统中引入先验信息是可以提升静态元素感知网络的上限的&#xff0c;这篇文章对SD地图采用栅格化表示&#xff08;也就是图像形式&#xff09;&#xff0c;之后用CNN网络去抽取栅格化SD地图的信息&…

linux ubuntu 在保存文件不被允许,但是root权限

现象&#xff1a;MobaXterm_Personal_2登录到服务器&#xff0c;切换到root用户&#xff0c;然后使用MobaXterm_Personal_2自带的编辑器&#xff0c;编写文件&#xff0c;进行保存不被允许&#xff1b;查看目录root是有权限进行修改文件的&#xff0c;然后使用vim进行修改保存&…

网络安全-内网渗透2

一、MIC 将我们上次未描述完的MIC在这里详细解释一下 咱们所抓的第二个包会给返回一个服务端的challenge 之后服务器回包的第三个包会回复一个client challenge 所以咱们客户端和服务端现在分别有两个challenge&#xff0c;相当于客户端和服务端互相交换了一下challenge 因此…

本地搭建多人协作ONLYOFFICE文档服务器并结合Cpolar内网穿透实现公网访问远程办公

文章目录 1. 安装Docker2. 本地安装部署ONLYOFFICE3. 安装cpolar内网穿透4. 固定OnlyOffice公网地址 本篇文章讲解如何使用Docker在本地服务器上安装ONLYOFFICE&#xff0c;并结合cpolar内网穿透实现公网访问。 Community Edition允许您在本地服务器上安装ONLYOFFICE文档&…

高精度(大整数)

本文用于记录个人算法竞赛学习&#xff0c;仅供参考 一.什么是大整数 当一个数的位数已经很大了&#xff08;比如有10^6&#xff09;&#xff0c;常规的数据类型已经存不下了&#xff0c;那么这个时候就可以用数组来存&#xff0c;数组的每个元素代表数的每一位&#xff0c;且…

Base64编码的全面介绍

title: Base64编码的全面介绍 date: 2024/3/31 18:55:49 updated: 2024/3/31 18:55:49 tags: Base64编码网络传输文本转换数据膨胀非加密性质应用场景安全传输 1. Base64的定义和作用 Base64是一种用64个字符表示二进制数据的编码方式&#xff0c;通常用于在网络传输中将二进…

什么是Redis数据一致性?如何解决?

在系统中缓存最常用的策略是&#xff1a;服务端需要同时维护DB和cache&#xff0c;并且是以DB的结果为准–Cache-Aside Pattern&#xff08;缓存分离模式、旁路缓存&#xff09; 读数据 单纯的读数据是不会产生数据不一致&#xff0c;只有并发下读和写才会存在数据不一致。 写…

安装即启动?探索流氓App的自启动“黑科技” (Android系统内鬼之ContentProvider篇)

前段时间发现了一个神奇的app&#xff0c;它居然可以在安装之后立即自启动&#xff1a; 看到没有&#xff0c;在提示安装成功大概1到2秒后&#xff0c;就直接弹出Toast和通知了&#xff01; 好神奇啊&#xff0c;在没有第三方app帮忙唤醒的前提下&#xff0c;它是怎么做到首次安…

2024年 前端JavaScript 进阶 第2天 笔记

2.1-内容和创建对象方式 2.2-164-构造函数 2.3-new实例化执行过程 2.4-实例成员和静态成员 2.5-基本包装类型 2.6-0bject静态方法 2.7-数组reduce累计方法 对象数组 加0 2.7-数组find、every和转换为真 --说明手册文档 MDN Web Docs 2.8-字符串常见方法 2.3 String 1.常见实例…