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

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

循环顺序队列类 !


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


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 ;
        }
    }
}
相关文章
|
4天前
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
19 5
【数据结构】优先级队列(堆)从实现到应用详解
|
10天前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
|
12天前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
12天前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
|
12天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
12天前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
13天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
16 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
17天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
19天前
crash —— 获取内核地址布局、页大小、以及栈布局
crash —— 获取内核地址布局、页大小、以及栈布局
|
1月前
栈的几个经典应用,真的绝了
文章总结了栈的几个经典应用场景,包括使用两个栈来实现队列的功能以及利用栈进行对称匹配,并通过LeetCode上的题目示例展示了栈在实际问题中的应用。
栈的几个经典应用,真的绝了