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

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

循环顺序队列类 !


                        循环顺序队列,在逻辑上是一个循环,也就是队首和队尾连接


65c6eabceeb5452694523d9f76885dac.png


                         循环顺序队列,在物理上就是一个数组 。


ae1466faa1b74954be325234719cd572.png


        循环顺序队列类Java语言描述【SqQueue】


—— 实现队列接口IQueue

package data.linear_table.stack_queue;
//循环队列类
public class SqQueue implements IQueue {
    private Object[] queueElem ;    //队列的存空间
    private int front ;             //队首的引用,若队列不为空,指向队首元素
    private int rear ;              //队尾的引用,若队列不为空,指向队尾元素的下一个存储位置
    //循环队列类的构造函数
    public SqQueue(int maxSize) {
        front = rear = 0 ;      //队首、队尾初始化为0
        queueElem = new Object[maxSize] ;       //为队列分配maxSize个存储单元
    }
    //队列置空
    @Override
    public void clear() {
        front = rear = 0 ;
    }
    //判断队列是否为空
    @Override
    public boolean isEmpty() {
        return front == rear;
    }
    //求队列的长度
    @Override
    public int length() {
        //(尾 - 头 + 队列长度) % 队列长度
        return (rear - front + queueElem.length)%queueElem.length ;
    }
    //读取队首元素
    @Override
    public Object peek() {
        if (front == rear) {
            //队列为空
            return null ;
        }else {
            //返回队首元素
            return queueElem[front];
        }
    }
    //入队
    @Override
    public void offer(Object x) throws Exception {
         //{..... }
    }
    //出队
    @Override
    public Object poll() {
        //{..... }
       return null ;
    }
    //输出队列中的所有数据元素(从队首到队尾)
    public void display () {
        //队列不为空
        if (!isEmpty()) {
            for (int i = front ; i != rear ; i = (i+1)% queueElem.length ) {
                System.out.print(queueElem[i].toString()+" ");
            }
        }else {
            System.out.println("此队列为空");
        }
    }
}

注: 代码中 ” {....}“ 处,会在后面单独进行讲解。

                       算法:入队

4fef1e1aebeb44eb86960bc47864f035.png


    //入队
    @Override
    public void offer(Object x) throws Exception {
        //判断是否已经满了,如果已经满了,抛异常
        //例头front = 0 ; rear = 4 ; 即queueElem.length = 5 ;
        //即:(rear+1) % queueElem.length = 5 % 5 = 0 = front  ;满足,即队列满
        if ( (rear+1) % queueElem.length == front) {
            throw new RuntimeException("队列满了");
        }else {
            //没有满进行入队操作
            //入队只能从队尾进行添加。队尾rear
            queueElem[rear] = x ;
            rear = (rear + 1) % queueElem.length ;     //队尾rear累加1 , 但最后时需要归零
        }
    }

ba41fff724364befbb96eb76ae4f4abf.png

    //出队
    @Override
    public Object poll() {
        if (front == rear) {
            //队列为空
            return null ;
        }else {
            Object t = queueElem[front] ;       //记录出队的元素
            front = (front+1) % queueElem.length ;      //重新赋值队首+1 ,并且要归0
            return t ;                  //返回队列的队首元素
        }
    }


(八) 链队列


        一、什么是链队列?


                        队列采用链式存储结构的队列叫链队列。


                        用两个指针front和rear 来分别队首元素和队尾元素。


41a474ac752e4d359ea5ab0282a51a8b.png


           二、链队列类【LinkQueue】


链表所需结点类:

package data.linear_table.node;
//单链表:结点类
public class Node {
    public Object data ;  //存放结点值
    public Node next ;    // 后继结点的引用
    //无参时的构造函数
    public Node() {
        this(null,null);
    }
    //带一个参数时的构造函数
    public Node(Object data) {
        this(data,null);
    }
    //带两个参数时的构造函数
    public Node(Object data , Node next) {
        this.data = data ;
        this.next = next ;
    }
}

LinkQueue类

 package data.linear_table.stack_queue;
import data.linear_table.node.Node;
//链队列类
public class LinkQueue implements IQueue {
    private Node  front ;   //队首指针
    private Node  rear ;    //队尾指针
    //链队列类的构造函数
    public LinkQueue () {
        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 front.data ;     //返回队首结点数据域值
        } else  {
            return null ;
        }
    }
    //入队
    @Override
    public void offer(Object x) throws Exception {
        //{...}
    }
    //出队
    @Override
    public Object poll() {
        //{...}
        return null
    }
}

注: 代码中 ” {....}“ 处,会在后面单独进行讲解。

                       算法:入队

eb5203853f724b46ae5374eba14c9050.png

  //入队
    @Override
    public void offer(Object x) throws Exception {
        Node p = new Node(x) ;      //初始化新结点
        if (front != null) {         //队列非空
            rear.next = p ;         //指向队尾指向新结点
            rear = p ;              //改变队尾的位置
        }else {
            //队列为空的话,新添加的这个就是队首元素
            front = rear = p ;
        }
    }

算法:出队

60f9932e2bd4470fb1847a6b764ebb76.png

    //出队
    @Override
    public Object poll() {
        if (front != null ) {       //队列非空
            Node p = front ;        //p指向队首结点,记录被删除的结点
           front = front.next ;     //队首结点移动到下一个
            if (p == rear ) {       //只有应该元素,删除的队首结点是队尾时
                rear = null ;
            }
            return p.data ;         //返回被删除的队首元素的数据域值
        }else {
            return null ;
        }
    }
}
相关文章
|
5天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
116 75
|
5天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
27 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
5天前
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
28 10
|
5天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
31 9
|
5天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
25 7
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
265 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
42 1
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
80 5
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
2月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。