数据结构—栈与队列【顺序存储、链式存储、卡特兰数、优先级队列】(四)

简介: 数据结构—栈与队列【顺序存储、链式存储、卡特兰数、优先级队列】

(九) 优先级队列


        一、什么是优先级队列?


                        它是一种带有优先级的队列,是一种比栈和队列更为专用的数据结构。


                        有一个队首和队尾。


                        在队首删除数据元素,顺序插入元素到队列的合适位置。


                        队列中的每一个数据元素按照关键字的值有序排列。


                        约定:关键字最小的数据元素(或者在某些实现中要求数据是最大的)具有最高优先级。


----------------------------------------------------------------------


       二、优先级队列使用顺序和链两个存储结构那个更好呢?

                        可采用顺序和链式两种存储结构。


                        考虑到优先级队列,既要保证能够快速的访问到优先级高的数据,又要保证可以实现快速的插入操作。所以通常以链式存储结构来实现优先级队列。


                        数据级别的高低依据优先数来鉴定,优先数越小,优先级别就越大。


----------------------------------------------------------------------


        三、优先级队列中结点的数据域data类【PriorityData】

package data.linear_table.node;
//优先队列中结点类的data类:数据域的值
public class PriorityQData {
    public Object elem ;        //结点的数据元素值
    public int priority ;       //结点的优先数
    //构造函数
    public PriorityQData (Object elem , int priority ) {
        this.elem = elem ;
        this.priority = priority ;
    }
}

e6322cda46c8437b859175da7219fd95.png

e1be80e2e5d840eca28f0f59feb20e55.png

package data.linear_table.stack_queue;
import data.linear_table.node.Node;
import data.linear_table.node.PriorityQData;
//优先队列【常以链式存储结构实现】
public class PriorityQueue implements IQueue {
    private Node front ;        //队首的引用
    private Node rear ;         //队尾的引用
    //优先队列类的构造函数
    public PriorityQueue () {
        front = rear = null ;
    }
    //队列置空
    @Override
    public void clear() {
        front = rear = null ;
    }
    //判断队列是否为空
    @Override
    public boolean isEmpty() {
        return front == null;
    }
    //求队列长度
    @Override
    public int length() {
        Node p = front ;
        int length = 0 ;
        while (p != null ){     //一直查到队尾
            p = p.next  ;
            length++ ;
        }
        return length ;
    }
    //读取首元素
    @Override
    public Object peek() {
        if (front == null ){
            return null;
        }else {
            return front.data ;         //返回队首结点的数据域值
        }
    }
    //入队
    @Override
    public void offer(Object x) {
       // {...}
    }
    //出队
    @Override
    public Object poll() {
        // {... }
       return null ;
    }
    //输出队列中的所有元素
    public void display() {
        if (!isEmpty()) {
            Node p = front ;
            while (p != null ) {
               PriorityQData q  = (PriorityQData)  p.data;
                System.out.println(q.elem+" " + q.priority);
                p = p.next ;
            }     //从队首到队尾
        }else {
            System.out.println("此队列为空!");
        }
    }
}

算法:出队

 //出队
    @Override
    public Object poll() {
        if (front == null){
            return null;
        }else {
            Node p = front ;    //保存记录要被删除的队首元素
            front = front.next ;        //队首指向下一个元素
            return p.data ;
        }
    }


算法:入队【数字越小,优先级越高】


                      情况1:队首插入(p如果指向队首front,表示新结点的优先级数字小)


df412bc3bfff4b21a352be39e95e8ef2.png


                                情况2:队尾插入(q为null 或p 等于队尾rear)


baa43da12e6740948d7893f14c49ef80.png


                                情况3:在两个元素的中间插入

05ef28924b5346a38043cc1790a35753.png

 //入队
    @Override
    public void offer(Object x) {
        PriorityQData pn = (PriorityQData) x ;
        Node s = new Node(pn) ;        //构造一个新结点
        //如果队列为空
        if (front == null) {
            front = rear = s  ;         //修改队列首结点
        }else {
            // 1) 移动:按照优先级进行移动,优先级大就需要移动
            Node p = front ;        //用于记录下一个
            Node q = front ;        //用于记录前驱(之前的)
            // 队首不为null ,并且新结点的优先级 >= 队列结点的优先级【两者进行比较】
            while (p != null && pn.priority >= ((PriorityQData)p.data).priority ) {
                //满足,
                q = p ;             //记录前驱
                p = p.next ;        //指向下一个
            }
            // 2) 插入
            //  2.1 情况一: 新结点的优先级比队尾还低
            if (p == null ) {       // p,遍历到下一个结点为空,表示遍历到了队列尾部
                rear.next = s;      //将新结点加入到队尾,队尾指针域next,指向新结点
                rear = s ;          //修改队尾指针
            // 情况二 : 新结点的优先级比队首还高
            }else if (p == front ) {
                s.next = front ;             //将新结点加入到队首,新结点s指向队首front
                front = s ;                     //修改队首指针
            // 情况三 : 新结点位于两个结点的中间
            }else {                         //新结点加入到队列中部
                q.next = s ;                //q是s的前驱结点,则s是q的下一个结点
                s.next = p ;                // s的下一个结点是p,则s为于 q 和 p 之间
            }
        }
    }

(十) 每日一练

41. 队列的插入操作在( )进行。


A.队头


B.队尾


C.队头或队尾


D.在任意指定位置


----------------------------------------------


42. 队列的删除操作在( )进行。


A.队头


B.队尾


C.队头或队尾


D.在任意指定位置


----------------------------------------------


43. 栈的插入操作在( )进行。


A.栈顶


B.栈底


C.栈顶或栈底


D.在任意指定位置


----------------------------------------------


44. 一个队列的入队序列是 2,4,6,8,则队列的输出序列是( )。


A.8,6,4,2


B.2,4,6,8


C.4,2,8,6


D.6,4,2,8


----------------------------------------------


45. 一个队列的入队序列是 5,6,7,8,则队列的输出序列是( )。


A. 5 6 7 8


B. 8 7 6 5


C. 7 8 6 5


D.可能有多种情况


----------------------------------------------


46. 一个栈的进栈序列是 1,2,3,4,则不可能的出栈序列是(  )(进出栈操作可以交替进行)。


A.3,2,4,1


B.1,4,2,3 1 4 3 2


C.4,3,2,1


D.3,2,1,4


----------------------------------------------


47. 一个栈的进栈序列是 5,6,7,8,则栈的不可能的出栈序列是(  )(进出栈操作可以交替进行)


A.5,8,6,7 5 8 7 6


B.7,6,8,5


C.7,6,5,8


D.8,7,6,5


----------------------------------------------


48. 一个栈的进栈序列是 a,b,c,d,e,则栈的不可能输出序列是( )(进栈出栈可以交替进行)。


A.dceab     ain bin cin din dout cout ein eout bout aout  --> dceba


B.edcba  ain bin cin din ein eout dout cout bout aout  --> edcba


C.decba     ain bin cin din dout ein eout cout bout aout  --> decba


D.abcde  ain aout bin bout cin cout din dout ein eout  --> abcde


----------------------------------------------


49. 以下说法不正确的是( )。


A.顺序栈中,栈满时再进行进栈操作称为“上溢”


B.顺序栈中,栈空时再作出栈栈操作称为“下溢”


C.顺序队列中,当尾指针已经超越队列存储空间的上界,则一定是队列已满。(假溢出)


D.顺序队列中,队列的头指针和尾指针均超越队列存储空间的上界,则队列已空


----------------------------------------------


50. 以下说法不正确的是( )。


A.栈的特点是后进先出


B.队列的特点是先进先出


C.栈的删除操作在栈底进行,插入操作在栈顶进行。 栈顶删除


D.队列的插入操作在队尾进行,删除操作在队头进行


----------------------------------------------


51. 以下说法正确的是( )。


A.栈的特点是先进先出,队列的特点是先进后出


B.栈和队列的特点都是先进后出


C.栈的特点是先进后出,队列的特点是先进先出


D.栈和队列的特点都是先进先出


----------------------------------------------


52. 以下说法正确的是( )。


A.栈的特点是先进先出,队列的特点是先进后出


B.栈和队列的特点都是先进后出


C.栈的特点是先进后出,队列的特点是先进先出


D.栈和队列的特点都是先进先出


----------------------------------------------


53. 元素 2,4,6,8 按顺序依次进栈,则该栈的不可能输出序列是( )(进栈出栈可以交替进行)。


A.8,6,4,2   2in 4in 6in 8in 8out 6out 4out 2out --> 8642


B.2,4,6,8   2in 2out 4in 4out 6in 6out 8in 8out --> 2468


C.4,2,8,6   2in 4in 4out 2out 6in 8in 8out 6out --> 4286


D.8,6,2,4   8642


----------------------------------------------


54. 元素 2,4,6 按顺序依次进栈,则该栈的不可能的输出序列是( )。


A. 6 4 2     2in 4in 6in 6out 4out 2out --> 642


B. 6 2 4     642


C. 4 2 6     2in 4in 4out 2out 6in 6out --> 426


D. 2 6 4     2in 2out 4in 6in 6out 4out --> 264


----------------------------------------------


55. 栈的插入删除操作在( )进行。


A.栈底


B.任意位置


C.指定位置


D.栈顶


----------------------------------------------


56. 栈和队列的相同点是( )。


A.都是后进先出


B.都是后进后出


C.逻辑结构与线性表不同


D.逻辑结构与线性表相同,都是操作规则受到限制的线性表


----------------------------------------------


57. 从一个栈顶指针为 top 的链栈中插入一个由 P 指向的新结点时,则执行的操作是()。


A.p.setNext(top); top=p;


B.top=p; p.setNext(top);


C.top.setNext(p); p=top;


D.top.setNext(p); p=top;


-----------------------------------------------------------------------


58. 设 top 是一个链栈的栈顶指针,栈中每个结点由一个数据域 data 和指针域 next 组成,


设用 x 接收栈顶元素,则出栈操作为( )。


A.x=top.getData(); top=top.getNext();


B.top=top.getNext();x=top.getData();


C.x=top.getNext(); top=top.getData();


D.top.setNext(top); x=top.getData();


-----------------------------------------------------------------------


59. 在一个链队列中,假设 f 和 r 分别为队头和队尾指针,则插入 s 所指结点的运算为(  )。


A.f.setNext(s); f=s;


B.r.setNext(s); r=s;


C.s.setNext(r); r=s;


D.s.setNext(f); f=s;


-----------------------------------------------------------------------


60. 在一个链队列中,假设 f 和 r 分别为队头和队尾指针,则删除一个结点的运算为(  )。


A.r=f.getNext();


B.r=r.getNext();


C.f=r.getNext();


D.f=f.getNext();


-----------------------------------------------------------------------


61. 在一个循环队列中,队列的空间大小为 length, 设对头指针为 front, 队尾指针为 rear,


按照教材采用减少一个存储元素的方法,以下那个能判断队列已满。 (  )


A. (rear+1)%length==front;


B. rear==front;


C. rear%length==front ;


D. (rear-1)%length==front;


-----------------------------------------------------------------------


62. 若一个栈用数组 data[1..n]存储,初始栈顶指针 top 为 n, 则如元素 x 进栈的正确操作是:(  )


A. top++; data[top]=x;


B. data[top]=x;top++;


C. top--;data[top]=x ;


D. data[top]=x;top--;


相关文章
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
210 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
35 1
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
1月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
1月前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
51 4
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
49 0
|
2月前
数据结构(栈与列队)
数据结构(栈与列队)
23 1
|
2月前
|
存储 安全 数据库
除了 HashMap,还有哪些数据结构可以实现键值对存储?
【10月更文挑战第11天】 除了`HashMap`,其他常见支持键值对存储的数据结构包括:`TreeMap`(基于红黑树,键有序)、`LinkedHashMap`(保留插入顺序)、`HashTable`(线程安全)、`B-Tree`和`B+Tree`(高效存储大量数据)、`SkipList`(通过跳跃指针提高查找效率)及`UnorderedMap`(类似`HashMap`)。选择合适的数据结构需根据排序、并发、存储和查找性能等需求。