zoukankan      html  css  js  c++  java
  • 队列---面试知识点整理

    数据结构包括逻辑结构和存储结构。

    逻辑结构包括集合、线性结构、树形结构、图形结构。

    存储结构包括顺序存储结构、链式存储结构、索引存储结构、哈希存储结构。

    “线性表”中的“线性”是逻辑结构的概念,是指

    (1)开始结点和终端结点都是唯一的;

    (2)除了开始结点和终端结点,其余结点都有且仅有一个直接前驱,有且仅有一个直接后继。

    “循环链表”中的“链表”是存储结构的概念,是指

    不要求逻辑上相邻的结点在物理上也相邻,结点间的逻辑关系是由附加的指针字段表示的。

    综上 ,循环链表也是链表的一种,链表满足线性表的条件,所以循环链表自然也属于线性表。

    栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。

    队列,是一种特殊的 线性表  ,特殊之处在于它只允许在表的前端( front )进行删除操作,而在表的后端( rear )进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头

    递归是栈实现的。栈是先进后出,也就是上次递归调用的时候,保存在栈顶, 在返回的时候出栈,所以是递归是依靠栈实现的.

    PS: 非递归形式的深度优先搜索要用栈,而广度优先使用了队列。

    某带链的队列初始状态为 front=rear=NULL 。经过一系列正常的入队与退队操作后, front=rear=10 。该队列中的元素个数为(  )

    往队列的队尾插入一个元素为入队,从队列的排头删除一个元素称为退队。初始时 front=rear=0 , front 总是指向队头元素的前一位置,入队一次 rear+1 ,退队一次 front+1 。队列队头队尾指针相同时队列为空。而带链的队列,由于每个元素都包含一个指针域指向下一个元素,当带链队列为空时 front=rear=Null ,插入第 1 个元素时, rear+1 指向该元素, front+1 也指向该元素,插入第 2 个元素时 rear+1 , front 不变,删除 1 个元素时 front+1 。即 front=rear 不为空时带链的队列中只有一个元素。

    当队列中只有一个元素时,出队后需要清空对头和队尾指针。

    线性结构与非线性结构,主要看元素之间的关系,如果是一对一的关系则是线性表,如果不是一对一的关系则是非线性表。

    循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。

    解决这个问题的方法至少有两种:

    ① 另设一布尔变量以区别队列的空和满;

    ②另一种方式就是数据结构常用的: 队满时:(rear+1)%n==front,n为队列长度(所用数组大小),由于rear,front均为所用空间的指针,循环只是逻辑上的循环,所以需要求余运算.

    队列元素=(尾指针-头指针+队列容量)%队列容量。循环队列中的元素个数随队头指针与队尾指针的变化而动态变化

    双端队列是一种同时具有队列和栈的性质的一种数据结构,在队列的两头都可以进行插入和删除的操作;输入受限的双端队列是指只能从队列一端输入,可以从两端输出的双端队列;同理,输出受限的双端队列是指只能从队列一端输出,可以从两端输入的双端队列;如果双端队列允许从一端输入,从一端输出,则是普通的队列,如果双端队列只允许从一端输入和输出则是栈。因此说双端队列同时具有队列和栈两种数据结构的性质。

    Redis和kafka都是常见的开源队列。

    队列是一种操作受限 的结构,即只能在队首删除和队尾插入

    栈是解决封闭对应问题的有效方法。

    比如在解析XML中,遇到一个<demo>标签(左标签)就入栈,遇到其子标签的左标签(如<subdemo>)同样入栈。遇到右标签(如</subdemo>或</demo>)就校验栈顶标签是否与该右标签对应,能对应就出栈,不能对应则说明标签不对称,是无效的XML文件

    存储结构是数据的逻辑结构用计算机语言的实现,常见的存储结构有: 顺序存储 , 链式存储 , 索引存储 ,以及 散列存储 。其中散列所形成的存储结构叫 散列表(又叫哈希表) ,因此哈希表也是一种存储结构。栈只是一种抽象数据类型,是一种逻辑结构,栈逻辑结构对应的顺序存储结构为顺序栈,对应的链式存储结构为链栈,循环队列是顺序存储结构,链表是线性表的链式存储结构

    用循环链表表示队列,必定有链表的头结点,题目中说链表设有尾指针。因此入队操作在链表尾插入,直接插入再尾指针指向的节点后面,时间复杂度是常数级的;出队操作在链表表头进行,也就是删除表头指向的节点,时间复杂度也是常数级的。

    在栈中,栈底保持不变,有元素入栈,栈顶指针增加;有元素出栈,栈顶指针减小。在循环队列中,队头指针和队尾指针的动态变化决定队列的长度。在循环链表中,前一个结点指向后一个结点,而最后一个结点指向头结点,只有头结点是固定的。线性链表中,由于前一个结点包含下一个结点的指针,尾结点指针为空,要插入删除元素,只需要改变相应位置的结点指针即可,头指针和尾指针无法决定链表长度。

    循环队列解决的是“假溢出”问题,但是仍然会出现真正的溢出问题。假溢出指的是下标溢出,真溢出指的是空间溢出。

    DFS是深度优先搜索,是后进先出,所以需要借助于一个栈来实现。而BFS,也就是广度优先搜索才是借助一个队列来实现

    循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设队头不存放数据)    (rear - front + N) % N

    下面数据结构能够支持随机的插入和删除操作、并具有较好的性能的是____。

    1,数组是在定义的时候申请一块连续的内存空间,访问某个元素只需要通过下标就可以,但是随机插入和删除都要移动后面所有的元素,所以,数组肯定不行;

    2,链表,是非连续的空间,通过指针访问,所以随机插入和删除通过指针之间的操作很方便,但是如果要查询一个数的时候还是得依次便利,但是题目问的是随机插入和删除,所以,链表可以;

    3,栈,所有的操作都是在栈顶,如果要随机插入或者删除某个数也必须依次对其他数就行操作,所以,栈也排除;

    4,队列,通过队头和队尾指针进行读入数据和删除数据,如果直接在队尾添加数据很方便,但是,题目中是随机,所以,队列排序;

    5,哈希表通过键值对操作,只要知道相关的key很容易就行读取和删除,插入某个元素也通过key很方便,所以,哈希表肯定可以;

    栈的常见应用:浏览器历史纪录,Android中的最近任务,Activity的启动模式,CPU中栈的实现,Word自动保存,解析计算式,解析xml/json

    循环队列的相关条件和公式:  

    队尾指针是rear,队头是front,其中QueueSize为循环队列的最大长度  

    1.队空条件:rear==front  

    2.队满条件:(rear+1) %QueueSIze==front  

    3.计算队列长度:(rear-front+QueueSize)%QueueSize  

    4.入队:(rear+1)%QueueSize  

    5.出队:(front+1)%QueueSize

  • 相关阅读:
    nginx能访问html静态文件但无法访问php文件
    LeetCode "498. Diagonal Traverse"
    LeetCode "Teemo Attacking"
    LeetCode "501. Find Mode in Binary Search Tree"
    LeetCode "483. Smallest Good Base" !!
    LeetCode "467. Unique Substrings in Wraparound String" !!
    LeetCode "437. Path Sum III"
    LeetCode "454. 4Sum II"
    LeetCode "445. Add Two Numbers II"
    LeetCode "486. Predict the Winner" !!
  • 原文地址:https://www.cnblogs.com/lxt1105/p/6671091.html
Copyright © 2011-2022 走看看