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

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

(四) 链栈


         一、什么是链栈?


                       使用链式存储的栈,就是链栈。


                       插入和删除操作在栈顶进行,也就是链表的尾端。


                       存储单元由2部分组成:数据域 data 和指针域 next 。


                        使用top栈顶指针用于指向栈尾


ff455bc4b417406bb8f8f4eb77df216f.png

二、链栈类 【LinkStack】

package data.linear_table.stack_queue;
import data.linear_table.node.Node;
//链栈类
public class LinkStack implements IStack {
    private Node top ;      //栈顶元素的引用
    //将栈置空
    @Override
    public void clear() {
        top = null ;
    }
    //判断链栈是否为空
    @Override
    public boolean isEmpty() {
        return top == null ;
    }
    //求链栈的长度
    @Override
    public int length() {
       //{...} 
        return 0 ;
    }
    //取栈顶元素并返回其值
    @Override
    public Object peek() {
        //栈如果不为空
        if (!isEmpty()) {
            //返回栈顶元素
            return top.data ;
        }else {
            return null ;
        }
    }
    //入栈
    @Override
    public void push(Object x) throws Exception {
        //{...}             
    }
    //出栈
    @Override
    public Object pop() {
        // {...}
        return null ;
    }
    //输出栈中所有数据元素(从栈顶元素到栈底元素)
    public void display() {
        Node p = top ;          //初始化,p指向栈顶元素
        while (p != null ) {    //输出所有非空结点的数据元素值
            System.out.print(p.data.toString()+" ");
            p = p.next ;        //p指针向后移
        }
    }
}


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


1. public class LinkStack {
2. private Node top;      //栈顶指针
3. }


算法:链栈的长度

  //求链栈的长度
    @Override
    public int length() {
        Node p = top ;      //初始化,p指向栈顶元素
        int length = 0 ;    //length为计数器
        //从栈顶元素开始向后查找,直到p为空
        while (p != null ) {
            p = p.next ;    //p指向后继结点
            length++ ;      //长度增加1
        }
        return length ;
    }

算法:入栈

public void push(Object x) {
    Node p = new Node(x);   // 创建新结点p
    p.next = top;    // 1.p的指针域指向栈顶元素
    top = p;      // 2.栈顶指针top指向新结点p
}

算法:出栈

public Object pop() {
    if(top == null) {     //空栈 isEmpty()
        return null; 
    } else {
        Node p = top;       // 1 存放栈顶元素
        top = top.next;     // 2 将top指向栈顶的下一个元素
        return p.data;      // 3 返回栈顶元素数据
    }
}

(五) 队列


       一、什么是队列?


                        队列是一个特殊的线性表。


                       只允许在队尾进行插入操作


                        只允许在队首进行删除操作


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


        二、队列的相关术语?


                        队尾rear:进行插入操作的一端。


                        队首front :进行删除操作的一端


                       入队offer : 进行插入操作,称为入队


                       出队 poll : 进行删除操作 , 称为出队

b54d5e43866e49c9bb9bab5116282360.png

三、 队列有哪两种存储方式 ?


                        使用顺序存储的称为顺序队列 。


                        使用链式存储的称为链队列 。


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


四、队列的抽象数据类型Java接口【IQueue】

package data.linear_table.stack_queue;
//队列的抽象数据类型Java接口
public interface IQueue {
    public void clear() ;   //置队成空队列
    public boolean isEmpty() ;  //判断队列是否为空
    public int length() ;   //队列中数据元素的个数
    public Object peek() ;  //取队列首元素
    public   void offer(Object x) throws Exception;  //将元素x插入到队列中使用成为新的队尾元素
    public Object poll() ;   //删除对首元素并返回其值。若队列为空,则返回null
}

(六) 顺序队列


        一、什么是顺序队列?


·                         顺序队列的存储结构中,需要分配一块地址连续的存储区域来一次存放队列中从队首到队尾的所有元素。


        二、关于队列的那些操作?


                        front表示队首,进行出队操作时,front进行计数。


                       rear表示队尾,进行入队操作时,rear进行计数。


                        front == rear == 0 为空队列。


                       入队操作:


97f2b06a3cfa441581b797823a33890a.png


                        出队操作:

11d71d82684b4f0f8e4fcfb6b5b52051.png

     


         三、队列存在的问题“假溢出”


                        因为顺序队列的多次入队和出队操作后出现有存储空间,但是又不能顺序入队的溢出现象,称为“假溢出”。


                       假溢出,数组的最后一个元素已经添加数据,但队列没有满 。


1a4d37f3e92849799b477f76a348d5ec.png


                         解决方案:使用循环队列解决“假溢出”问题。将顺序队列所使用的存储空间看成是一个逻辑上首尾相连的循环队列。


915b2a20d4a04a808ca2b6f621cfb4bc.png


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


(七) 循环顺序队列


        一、什么是循环顺序队列?


                        在逻辑上队首和队尾连接在一起。


                       存在的问题:队首front和队尾rear重叠时,无法区分队满还是队空。


193344d7c4e04c8ab91dbe5c00df04f6.png


                        解决方案 :


                               方案1:设计一个计数器,出入队累计法。(整数变量num,入队+1,出队-1,如果num=0就是空)。判断条件为:num == 0 为队空;num > 0 && front == rear 为队满。


                               方案2:设计一个标识变量法。(flag=0出队,flag=1入队,重叠后0表示空,1表示满)。判断条件为:front == rear && flag == 0 为队空;front == rear && flag == 1 为队满。


                               方案3:少用一个存储单位。当顺序存储空间为maxSize时,只允许最多存放maxSize -1个数据元素。判断条件为:


// 队列空
front == rear;
// 队列满
(rear + 1) % maxSize == front;

2d861fd7d7944b75a6b8cf994c0267b8.png

详解   front == (rear+1) % maxSize 为 队满 :

547c5864a6e045ba884d7ecfd8cf5925.png




相关文章
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
41 1
|
20小时前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
24 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
19小时前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
104 69
|
20小时前
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
23 10
|
20小时前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
21 7
|
20小时前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
22 9
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
76 5
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
2月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
2月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
57 0
下一篇
开通oss服务