首页 > 其他分享 > 数据结构之栈和队列

数据结构之栈和队列

时间:2023-10-28 23:31:35浏览次数:36  
标签:之栈 队列 元素 入队 出队 数组 myQueue 数据结构

一:物理结构和逻辑结构

除了数组和链表之外,常用过的数据结构还有很多,但大对数

*  都以数组或链表作为存储方式。数组和链表可以被看作数据存储

*  地‘物理结构“

*

* 什么是数据存储的物理结构呢?

* 如果把数据结构比作活生生的人,那么物理结构就是人的血肉

* 和骨骼,看得见,摸得着,实实在在。例如我们刚刚学过的数组和链表,都是内存中实实在在

* 存储结构

* 而在物质人体之上,还存在着人的思想和精神,它们看不见,摸不着。

* 看过电影《阿凡达》的:男主角的思想意识从认识一个瘦弱残疾的人类身上被移植

* 到一个高大威猛的蓝皮肤外星人身上,虽然承载着思想意识的肉身改变了,但是人格确实唯一的。

* 如果把物质层面的人体比作数据存储的物理结构,那么精神层面的人格则是

* 数据存储的逻辑结构。逻辑结构实是抽象的概念,它依赖于物理结构存在。

* 逻辑结构  线性结构:举例(顺序表、栈、队列)

*         非线性结构 举例(数、图)

*

* 物理结构  顺序存储结构 举例(数组)

*          链式存储结构 举例(链表)

二:栈和队列

什么是栈?
 * 假如有一个又细又长的圆筒,圆筒一端封闭,另一端开口,往圆筒里面放入兵乓球,先放入
 * 的靠近圆筒底部,后放入的靠近圆筒入口。
 * 那么,要想取出这些乒乓球,则只能按照和放入顺序相反的顺序来取,先取出
 * 后放入的,再取出先放入的,而不能把最里面最先放入的乒乓球优先取出
 * 。
 * 栈:是一种线性数据结构,它就像一个上图所示的放入乒乓球的圆通容器,栈中的元素只能
 * 先入后出(First Last Out,简称FILO)。最早进入的元素存放在位置叫做栈底,最后进入的元素存放在
 * 的位置叫作栈顶。
 *   栈这种数据结构既可以用数组来实现,也可以用链表来实现。
 *    栈底                栈顶
 *    3    5   1   4   9   6   null  null
 *
 *    栈的基本操作:
 *    1. 入栈
 *    入栈操作(push)就是把新元素放入栈中,只允许从栈顶一侧放入元素,新元素
 *    的位置将会成为新的栈顶。
 *
 *    2. 出栈操作
 *     出栈操作(pop)就是把元素从栈中弹出,只有栈顶元素才允许出栈
 *     ,出栈元素的前一个元素将会成为新的栈顶。
 *     由于栈操作的代码实现比较简单,这里就不在展示代码了。
 *     入栈和出栈只会影响到最后一个元素,不涉及其他元素的整体移动
 *     所以无论是以数组还是以链表实现,入栈、出栈的时间复杂度都是O(1)
 *
 * */


/**
 *   什么是队列
 *   要弄明白什么是队列?举一个例子来说明
 *   假如公路上有一条单行隧道,所有通过隧道的车辆
 *   只允许隧道入口驶入,从隧道出口驶出,不允许逆行。
 *
 *   因此,要想让车辆驶出隧道,只能按照它们驶入隧道的顺序,先驶入的车辆先驶出
 *   后驶入的车辆后驶出,任何车辆都无法跳过前面的车辆提前驶出的
 *
 *   队列是一种线性数据结构,它的特征和行驶车辆的单行隧道很相似。不同于栈的先入后出
 *   队列中的元素只能先入先出(First In First Out,简称FIFO)。队列的出口端叫做队头
 *   队列的入口端叫作队尾(rear)
 *   与栈类似,队列这种数据结构既可以用做数组来实现,也可以用链表来实现
 *    用数组实现时,为了入队操作的方便,把队尾位置规定为最后入队元素的下一个位置
 *    队列的数组实现如下:
 *    队头                         队尾
 *    3    5    1   4   9    6    null     null
 *
 *
 *    队列的基本操作:
 *    对于链表实现方式,队列的入队、出队操作和栈是大同小异的,对于实现来说,队列
 *    的入队和出队操作有了一些变化。
 *
 *    1. 入队
 *      入队(enqueue)就是把新元素放入队列中,只允许在队尾的位置放入元素,新元素
 *      的下一个位置将会成为新的的队尾。
 *
 *   2 出队
 *      出队操作(dequeue)就是把元素移出队列,只允许在队头一侧移出元素,出队元素
 *      的最后一个元素将会成为新的队头
 *    思考: 如果像这样不断的出队,队头左边的空间失去了作用
 *   那队列的容量岂不是越来越小了。
 *
 *    用数组实现的队列可以采用循环队列的方式来维持队列容量的恒定
 *
 *    循环队列:举例
 *    假设一个队列经过反复的入队和出队操作,还剩下两个元素,在“物理”
 *    上分布于数组末尾位置。这时又有一个新元素将要入队。
 *
 *    在数组不断做扩容的前提下,如何让元素入队并确定新的队尾位置呢?
 *    我们可以利用已出队的元素留下的空间,让队尾指针重新指回
 *    数组的首位。
 *    这样一来,整个队列的元素就“循环“起来了,在物理存储上,队尾的位置也可以
 *    在队头之前。当再有元素入队时,将其放入数组的首位,队尾指针继续后移即可
 *
 *    一直到(队尾下标+1) % 数组长度 = 队头下标时,代表队列真的已经满了。需要注意的是,
 *    队尾指针指向的位置永远空出1位,所以队列最大容量比数组长度小1。
 *
 * */

队列的基本操作举例:

// 循环队列的实现

private int[] array;
private int front;
private int rear;


public MyQueue(int capacity) {
    this.array = new int[capacity];
}



/**
 *
 * 入队
 * @param element 放入元素
 *
 *
 **/
public void enQueue(int element) throws Exception {
    if((rear + 1) % array.length == front) {
        throw new Exception("队列已满!");
    }
    array[rear] = element;
    rear =(rear + 1) % array.length;
}


/**
 * 出队
 *
 *
 * */

public int deQueue() throws Exception {
    if(rear == front) {
        throw new Exception("队列已空!");
    }
    int deQueueElement = array[front];
    front = (front + 1) % array.length;
    return deQueueElement;

}




/**
 *
 *
 * 输出队列
 *
 * */

public void output() {
    for(int i = front; i != rear; i = (i + 1) % array.length) {
        System.out.println(array[i]);
    }
}


public static void main(String[] args)  throws Exception{
    MyQueue myQueue = new MyQueue(6);
    myQueue.enQueue(3);
    myQueue.enQueue(5);
    myQueue.enQueue(6);
    myQueue.enQueue(8);
    myQueue.enQueue(1);
    myQueue.deQueue();
    myQueue.deQueue();
    myQueue.deQueue();
    myQueue.enQueue(2);
    myQueue.enQueue(4);
    myQueue.enQueue(9);
    myQueue.output();

                                              数据结构之栈和队列_数组

                 

循环队列不但可以充分利用数组的空间,还避免了数组元素整体移动的麻烦 , 至于入队和出队的时间复杂度,也同样是O(1)

三:栈和队列的应用

栈和队列的应用
* 1.栈的应用
* 栈的输出顺序和输入顺序相反,所以栈通常用于
*对”历史“的回溯,也就是逆流而上追溯”历史“
*例如实现递归的逻辑,就可以用栈来代替,因为栈可以回溯方法调用链
*
*栈还有一个著名的应用场景是面包屑导航,使用护在浏览界面时可以轻松追溯到上一级或更上一级
*页面。
*
* 2.队列的应用
*  队列的输出顺序和输入顺序相同,所以队列通常用于对”历史的回放“也就是按照”历史“的顺序把
*  ”历史“重演一遍。
*  例如:在多线程中,争夺公平锁的等待队列,就是按照访问顺序来决定线程在队列
*  中的次序的。
*  再如网络爬虫实现网站爬取时,也是把待抓取的网站的URL队列当中,
*  再按照存入队列的顺序来依次抓取和解析的。
*
*
*  3.双端队列:
*  双端数列这种数据结构,可以说是综合了栈和队列的优点,对双端队列来说,从队头
*  一端可以入队或者出队,从队尾一端也可以入队或者出队。
*
*
*  4.优先队列
*  还有一种队列,它遵循的不是先入先出,而是谁的优先级最高,谁先出队。
*
* 优先队列已经不属于线性数据结构的范畴了,它是基于二叉堆来实现的。关于优先队列的原理和使用情况后面再说
*
*
* */


标签:之栈,队列,元素,入队,出队,数组,myQueue,数据结构
From: https://blog.51cto.com/u_15912723/8073217

相关文章

  • 重学递归思想,体悟数据结构奥妙
       说来好笑,暑假一腔热血想进acm,在学插入排序,归并排序这两个玩意,耗费了我整整一个星期都没搞懂,一度让我想放弃,觉得自己刚开始学算法就被打败了,不配coding了,后面请教别人,才发现里面有个递归思想我还不会,所以很痛苦。。。暑假结束了,递归我还没那么懂,今天来复仇了     ......
  • Python数据结构——链表
    链表(LinkedList)是一种基本的数据结构,用于组织和管理数据。它是由一系列节点(Node)组成的数据结构,每个节点包含一个数据元素和指向下一个节点的引用。链表是一种非线性数据结构,与数组不同,它可以根据需要动态分配内存。什么是链表?链表是由节点组成的数据结构,每个节点包含两部分:数据元......
  • Java基础 阻塞队列的方式实现等待唤醒机制,哪里体现了等待?哪里又体现了唤醒?
    Java的阻塞队列(BlockingQueue)可以用来实现等待唤醒机制,其中等待和唤醒的操作在队列的不同方法中体现:1.等待:在阻塞队列中,等待通常发生在以下情况:2.当队列为空时,消费者线程试图从队列中取出元素时,它会被阻塞,直到队列中有元素可供消费。这种等待是通过阻塞队列的take()方法来实现......
  • Java基础 等待唤醒机制(阻塞队列方式实现)
    等待唤醒机制还可以用阻塞队列的方式进行实现    练习:利用阻塞队列完成生产者和消费者(等待唤醒机制)的代码细节:生产者和消费者必须使用同一个阻塞队列阻塞队列的创建方式(泛型:队列里面数据的类型):ArrayBlockingQueue<String> queue = new  ArrayBlockingQueue<......
  • 数据结构与算法(LeetCode) 第二节 链表结构、栈、队列、递归行为、哈希表和有序表
    一、链表结构1.单向链表节点结构publicclassNode{ publicintvalue;publicNodenext;publicNode(intdata){value=data;}}2.双向链表节点结构publicclassDoubleNode{publicintvalue;publicDoubleNodelast;publicDouble......
  • 数据结构与算法(LeetCode)第一节:认识复杂度,对数器,二分法与异或运算
    一、认识复杂度1.评估算法优劣的核心指标:时间复杂度:当完成了表达式的建立,只要把最高阶项留下即可。低阶项都去掉,高阶项的系数也去掉,记为O(去掉系数的高阶项);​ 时间复杂度是衡量算法流程的复杂度的一种指标,该指标只与数据量有关,与过程之外的优化无关常见的时间复杂度(从好到坏)O......
  • [考研] 数据结构
    针对数据结构的部分学习笔记。栈出栈排列个数:\(C_{2n}^n\),卡特兰数栈模拟中缀转后缀原理:中缀转后缀的原理是单调栈(维护一个优先级递增的栈),从栈底到栈顶的优先级必然递增,输出时可以保证优先级高的先输出(出栈)。中缀表达式和后缀表达式的不同仅在于符号位置不同,数字之间相......
  • 评论功能的选择难题:数据结构如何选定?
    尊敬的小伙伴们,大家好!我是小米,一个热爱技术、热衷分享的90后程序员。今天,我要和大家一起探讨一个在软件开发中常见,却又充满深度的话题——"面试题:评论功能采用什么数据结构?"。在这个数字化时代,几乎每个应用程序都需要实现评论功能。无论是社交媒体、电子商务网站还是新闻阅读应用,评......
  • 西北电专大二电院_数据结构上机报告记录_第二次上机报告
    第二次上机报告只要求提交了顺序串和顺序栈的基本操作的实现,这里把剩下两个也补充上去 顺序栈——进制转换1.问题描述本程序基于栈功能实现一个进制转换程序。(用顺序栈完成此题)InitStack()函数用于构造一个空栈;StackEmpty()函数用于判断栈是不是空栈;Push()函数实现将......
  • 数据结构与算法 → 深入数据结构
    前置知识前端数据及结构-链表-单向链表......