首页
学习
活动
专区
圈层
工具
发布

栈 | 如何使用数组和链表实现“栈”

下面是一个栈的入栈和出栈整个过程 [n0po5i62v6.png] 栈的实现有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。...数组实现 分析 在采用数组来实现栈的时候,栈空间是一段连续的空间。...实现思路如下图所示 [c9blp66jg9.png] 从上图中可以看出,可以把数组的首元素当作栈底,同时记录栈中元素的个数size,假设数组首地址为arr,压栈的操作其实是把待压栈的元素放到数组arrsize...根据这个原理可以非常容易实现栈。...分析 在创建链表的时候经常采用一种从头结点插入新结点的方法,可以采用这种方法来实现栈,最好使用带头结点的链表,这样可以保证对每个结点的操作都是相同的,实现思路如下图所示。

1.4K40
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【数据结构】栈和队列

    前言 栈作为一种比较特殊的存储结构,可以使用数组、单链表、双向链表等多种方法来实现,其在函数调用和递归、表达式求值、浏览器的历史记录、撤销操作、系统调用等多个场景中被广泛使用。...2、实现栈的方法选择 了解的栈的结构,接下来就要考虑如何实现栈。 在这之前我们学习了顺序表(底层就是数组)和链表,链表又分单链表和双向链表,用哪个方法实现效果最好呢?...上篇文章中我们简单地列举的顺序表和链表的比较,如下: 顺序表 链表(双向链表) 存储空间上 逻辑、物理上都连续 逻辑上连续、物理上不一定连续 随机访问 复杂度O(1) 复杂度O(N) 任意位置插入或删除数据...4、用栈解决括号匹配的问题 题目:有效的括号—leetcode 题目描述: 我们怎么使用栈的特点来解决这个问题呢? 解题思路: 返回false的情况有两种,一种是数量不匹配,一种是顺序不匹配。...栈和队列比较: 队列既可以用链表实现也可以用数组实现,但单链表结构总体更优一些。

    25110

    速学数据结构 | 链表实现队列究竟有什么优势?

    而队列的主要操作就是下面俩条: 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 二、 队列的实现 队列其实也可以用我们学过的数组或者链表实现但是,用数组的话头删要把整个尾部的数据拉过来覆盖前面消耗太大了...队列也可以数组和链表的结构实现,使用链表的结构实现更优一些 如果使用数组的结构,出队列在数组头上出数据,效率会比较低 2.1 队列的结构 那么队列的结构该如何定义呢?...那就在定义一个 size 来记录队列的长度就可以非常简单的解决问题了 代码演示: typedef int QDataType; typedef struct QueueNode { struct QueueNode...用来记录队列的元素这个时候就派上用场了。...❤️ 拜托拜托这个真的很重要! 你们的点赞就是博主更新最大的动力! 有问题可以评论或者私信呢秒回哦。

    35910

    如何高效对有序数组链表去重?

    所以对于一般处理数组的算法问题,我们要尽可能只对数组尾部的元素进行操作,以避免额外的时间复杂度。 这篇文章讲讲如何对一个有序数组去重,先看下题目: ?...而且题目要求我们原地修改,也就是说不能用辅助数组,空间复杂度得是 O(1)。 其实,对于数组相关的算法问题,有一个通用的技巧:要尽量避免在中间删除元素,那我就先想办法把这个元素换到最后去。...这样的话,最终待删除的元素都拖在数组尾部,一个一个 pop 掉就行了,每次操作的时间复杂度也就降低到 O(1) 了。 按照这个思路呢,又可以衍生出解决类似需求的通用方式:双指针技巧。...这样当fast指针遍历完整个数组nums后,nums[0..slow]就是不重复元素,之后的所有元素都是重复元素。 ? 看下算法执行的过程: ? 再简单扩展一下,如果给你一个有序链表,如何去重呢?...其实和数组是一模一样的,唯一的区别是把数组赋值操作变成操作指针而已: ? 对于链表去重,算法执行的过程是这样的: ? 最后,近期准备写写一些简单实用的数组/链表技巧。

    1.8K20

    数据结构之队列详解(包含例题)

    二、模拟实现顺序队列 我们可以用单链表模拟实现顺序队列。...队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部(对应单链表的尾插),而读取的时候总是从链表的头部开始读取。...(Que* pq); void QueueDestory(Que* pq); void QueuePush(Que* pq, QDataType x); void QueeuPop(Que* pq);...注意本题结构较为复杂,必须要画图进行解决,这样就容易考虑到特殊情况,不容易出错。 本题用数组实现较为简单,如果用单链表实现,那么rear尾结点的前一个不好寻找。 那数组如何实现循环呢?...数组实现循环并不像单链表那样有一个next指针指向头结点,如果已经走向尾部,可以直接让头部的值等于尾部想要的值。 //如何用数组实现循环?

    32510

    队列 | 如何使用数组和链表来实现“队列”

    如何使用数组和链表来实现“队列” 与栈一样,队列(Queue)也是一种数据结构,它包含一系列元素。但是,队列访问元素的顺序不是后进先出(LIFO),而是先进先出(FIFO)。 ? ?...与实现栈的方法类似,队列的实现也有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。...OK,自此,使用数组实现队列已经搞定。 问题 出队列后数组前半部分的空间不能够充分地利用,解决这个问题的方法为把数组看成一个环状的空间(循环队列)。...当数组最后一个位置被占用后,可以从数组首位置开始循环利用。 链表实现 分析 采用链表实现队列的方法与实现栈的方法类似,分别用两个指针指向队列的首元素与尾元素,如下图所示。...OK,使用链表实现队列到此就搞定。 总结 显然用链表来实现队列有更好的灵活性,与数组的实现方法相比,它多了用来存储结点关系的指针空间。

    2.1K20

    《代码随想录》笔记

    判断链表是否环 分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。...fast指针一定先进入环中,如果fast指针和slow指针相遇的话,一定是在环中相遇 如果有环,如何找到这个环的入口 index1 指针在环里 多转了(n-1)圈,然后再遇到index2,相遇点依然是环形的入口节点...我们需要依靠哈希表中的空位来解决碰撞问题。...输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。...括号匹配是使用栈解决的经典问题。

    41510

    根据身高重建队列

    每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。 请你重新构造并返回输入数组 people 所表示的队列。...people.length <= 2000 0 <= hi <= 10^6 0 <= ki < people.length 题目数据确保队列可以被重建 思路 本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度...O(n) 但使用vector是非常费时的,C++中vector(可以理解是一个动态数组,底层是普通数组实现的)如果插入元素大于预先普通数组大小,vector底部会有一个扩容的操作,即申请两倍于原先普通数组的大小...关于本题使用数组还是使用链表的性能差异,我在贪心算法:根据身高重建队列(续集)中详细讲解了一波 总结 关于出现两个维度一起考虑的情况,我们已经做过两道题目了,另一道就是135. 分发糖果。...最后我给出了两个版本的代码,可以明显看是使用C++中的list(底层链表实现)比vector(数组)效率高得多。 对使用某一种语言容器的使用,特性的选择都会不同程度上影响效率。

    53220

    数组拷贝或克隆?看这篇全面解决方案

    前言  在Java开发中,经常需要对数组进行拷贝或者克隆的操作。这个操作看似简单,但是实际却有很多需要注意的地方。...本文将介绍如何正确的对Java数组进行拷贝或者克隆,以及在实际开发中常见的应用场景和优缺点分析。摘要  本文主要介绍Java中对数组进行拷贝或者克隆的操作,并针对不同的应用场景给出最佳实践。...这段代码是一种对数组进行复制的常用方法,可以用于创建一个原数组的副本,或者创建一个长度相同但内容不同的新数组。注意,这个方法只复制数组的值,而不会影响原数组的值。...这个方法的第一个参数是原数组,第二个参数是要复制的起始索引,第三个参数是要复制的结束索引(不包括该索引)。...测试结果  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

    49021

    Python 中如何向列表或数组添加元素

    给初学者的定义编程中的数组是一个有序的项目集合,所有的项目都需要是相同的数据类型。然而,与其它编程语言不同,数组在 Python 中不是一个内置的数据结构。Python 使用列表取代传统的数组。...尽管列表有可能只容纳相同数据类型的项目,但它们比传统的数组更灵活。这意味着在同一个列表中可以有各种不同的数据类型。列表有 0 个或更多的项目,这意味着也可以有空的列表。在一个列表中,也可以有重复的值。...如何在 Python 中创建列表要创建一个新的列表,首先给这个列表起一个名字。然后添加赋值运算符(=)和一对有开头和结尾的方括号。在方括号内添加你希望列表包含的值。...集合中的每个项目都有一个自己的索引号,你可以用它来访问这个项目本身。Python(以及其它现代编程语言)中的索引从 0 开始,列表中的每一项的索引逐个增加。...extend() 的工作方式是,它将一个列表(或其他可迭代的)作为参数,对每个元素进行迭代,然后将可迭代的每个元素添加到列表中。.append() 和 .extend() 之间还有一个区别。

    4.4K20

    C++从 STL 中的队列开始说起

    本文将先从STL的队列说起,然后讲解如何自定义队列。 2. STL 中的队列 STL的队列有: queue(普通队列)。 priority_queue(优先队列)。 deque(双端队列)。...这个就需要从它的物理结构说起。 deque物理结构中的基本存储单位称为段,段是一个连续的可存储 8 个数据的顺序区域。...自定义队列 队列有 2 种实现方案: 顺序实现,基于数组的实现方案。 链表实现,基于链表的实现方案。 3.1 顺序实现 顺序实现底层使用数组作为具体存储容器。实现之初,需要创建一个固定大小的数组。...可以使用 2 种方案解决这个问题: 计数器方案。使用计数器记录队列中的实际数据个数。当num==0时队列为空状态,当num==size时队列为满状态。...总结 本文讲解了STL中的队列组件,以及如何通过顺序表和链表模拟队列。

    1.3K10

    《数据结构初阶》【顺序栈 + 链式队列 + 循环队列】

    通过环形缓冲区的方式解决普通顺序队列的"假溢出"问题,实现循环利用存储空间的目的。 其核心特点是将数组的首尾逻辑相连,使得当队列尾部到达数组末端时能够绕回到数组开头继续存储数据。...顺序栈初始化时该如何初始化top?...newNode->val = x; //3)将这个节点链接到队列链表的后面 //3.1:将新开辟的节点的next指针域置空 newNode->next = NULL; //3.2:将新开辟的节点链接到队列链表的尾部...newNode->val = x; //3)将这个节点链接到队列链表的后面 //3.1:将新开辟的节点的next指针域置空 newNode->next = NULL; //3.2:将新开辟的节点链接到队列链表的尾部...isFull && front == rear isFull && front == rear 总结:预留空位法最常用,并且C++ STL中也是使用的预留空位法解决的如何判断循环队列空or满?

    22410

    日拱一卒,LeetCode23,攻克难题从这道题开始吧

    废话不多说,我们来看这道题的题意: 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 题意很简单,就是让我们把K个有序的链表合并。...相信大家也都注意到了,有一个关键的信息被我们忽略了——链表本身都是有序的。 我们的方法固然能够解决问题,但没有利用上这个条件,最后额外进行了排序。...比如优先队列,优先队列可以保证队列中的元素保持有序,队首的元素最小或最大。...que.empty()) { pnt->next = new ListNode(que.top()); que.pop(); pnt...que.empty()) { auto f = que.top(); que.pop(); pnt->next = new ListNode

    34810

    二叉树构建与遍历-LeetCode 103、108、109(二叉树的构建,层次遍历)

    解题思路: 这道题目依然是层次遍历的应用,与剑指Offer中的"之字形打印二叉树"是一样的,根据层次遍历的思路,可以将每一层压入到数组中,当层数为奇数的话,从而将该层的数据压入数组中,并进行反转!...root) return res; queue que; que.push(root); int flag = 0;...que.empty()){ vector tmp; int size = que.size(); while(size-...解题思路: 这个思路和二分查找有些类似,由于本题目中也是有序数组,因此可以使用这种方法,因此可以将数组分割得两部分,对于BST树来说,针对于root节点,其左子树的节点必定小于root节点的值,而右子树的节点也必定大于...解题思路: 快慢指针的算法,首先利用快慢指针找到链表的中心点,然后截取链表,即二叉树的root节点。然后用递归的方式去构建左右子树!

    63370

    【图论-存图】邻接矩阵 邻接表 链式前向星

    ,也就是这样 但是仔细想想,有很多不必要的空间浪费,比如说(2,5)这个空间就没有必要,那我们可以像一个办法来去掉这些多余的空间,邻接矩阵我们用的是二维数组,那这里我们想一下,根据每一个点到另一个点不同...而动态数组,在C语言里面我们用链表,如果是C++的话,用vector。...,如果是用的链表,那遍历的顺序就会倒过来,因为链表的插入通常使用头插法,当然,你使用尾插法也可以) 下面直接上代码 先来一个链表的 zhetypedef struct edgeNode{ int...=true) { Que.push(V[Que.front().edge[i].index]); book[Que.front().edge...当然如果你要弄成无向图的话,再反过来添加就可以了 如果是无向图的话,插入第一个点是这样的 然后,我们把1 4 3插入(这个图因为是无向图,所以这个地方,e的下标是2) 所以说这个插入顺序和链接顺序有点像栈

    98953

    java.lang.IllegalArgumentException 如何解决这个异常

    很多人说这个异常是spring版本和jdk版本不一致导致的,其实不然你可以运行一下这一段代码 public static void main(String[] args) {...也可以是你自已给的一个随机的或是别人给你的时间戳(一定是long型的数据) SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//这个是你要转成后的时间的格式...也可以是你自已给的一个随机的或是别人给你的时间戳(一定是long型的数据) SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//这个是你要转成后的时间的格式...会造成这个问题,如果我们把String类型的时间戳转换成Long 类型的时间戳再转换成时间就解决了。希望我的博客对你有帮助。

    1.8K10
    领券