当前位置: 首页 > news >正文

栈(Stack)和队列(Queue)

栈(stack)是一种特殊的线性表,只允许在固定的一端进行插入和删除操作。

我们可以将栈近似看作一个桶,要取出桶底的元素,就要将桶顶的元素先取出,再将底部元素取出,也可以叫做后进先出。

这里所见的栈,本质上是一个顺序表/链表,但是,是在线性表/链表的基础上进行了一些限制。

对于栈而言,禁止了顺序表/链表的各种增删改查,只支持三个操作,入栈(push),出栈(poll),取栈顶元素(peek),可以认为栈是只能进行头删,尾删,取尾部元素的顺序表/链表。

栈存在的意义

既然栈可以用链表和顺序表/链表替代,那么为什么要将它单独存在。

编程中的一个基本原则,一个东西越灵活,越容易出错,越死板越不易出错,顺序表链表这样的结构功能太丰富,太灵活,所以栈/队列针对特定的场景,对顺序表和链表功能进行限制,大大减少出错的概率,栈虽然功能上做出限制,但是在特定场景下,解决特定问题的特定手段。

栈的实现

public static void main(String[] args) {Stack<Integer> k = new Stack<>();//元素入栈k.push(1);//元素出栈k.pop();//取栈顶元素k.peek();}

虽然栈是功能做出限制,让使用更简单,应该只提供三个方法,但是JAVA标准库中,Stack这个类的实现,其实是继承了Vector这样的类(Vactor是顺序表,与ArrayList差不多的,前者是上古时期的顺序表),但是Stack继承自Vactor,导致Vactor的各种操作,Stack也继承下来了。

模拟实现栈

栈可以用链表和顺序表实现。

public class MyStack {private int [] elem;private int size =0;public MyStack(){elem = new int [100];}public MyStack(int cope){if(cope<=100){cope=100;}elem = new int[cope];}public void push(int elems){elem[size] = elems;size++;}public int pop(){if(size==0){throw new RuntimeException();}int j = elem[size-1];size--;return j;}public String peek(){if(size==0){return null;}return Integer.toString(elem[size-1]);}}

逆序单链表

逆序单链表可以用递归和栈。

递归实现:

public class stack2 {static class Node{String val ;Node next = null;public Node(String val) {this.val = val;}}public static void reparent(Node head){if(head==null){return;}reparent(head.next);System.out.println(head.val);}public static Node Build(){Node a = new Node("a");Node b = new Node("b");Node c = new Node("c");Node d = new Node("d");a.next = b;b.next = c;c.next = d;return a;}public static void main(String[] args) {Node head = Build();reparent(head);}
}

栈实现:

public class stack2 {static class Node{String val ;Node next = null;public Node(String val) {this.val = val;}}public static void reparent(Node head){
//        if(head==null){
//            return;
//        }
//        reparent(head.next);
//        System.out.println(head.val);Stack<String> stack = new Stack<>();for (Node cur = head;cur!=null;cur = cur.next){stack.push(cur.val);}while(!stack.isEmpty()){System.out.println(stack.pop());}}public static Node Build(){Node a = new Node("a");Node b = new Node("b");Node c = new Node("c");Node d = new Node("d");a.next = b;b.next = c;c.next = d;return a;}public static void main(String[] args) {Node head = Build();reparent(head);}
}

队列(Queue)

队列,也是针对线性表,进行进一步的封装和限制,提供的操作也是是三个操作,入队列,出队列,取队首元素。

先进先出

队列实现

public static void main(String[] args) {//用链表实现QueueQueue<Integer> integers = new LinkedList<>();integers.offer(1);integers.offer(2);integers.offer(3);integers.poll();integers.peek();//判定队列是否为空if(integers.peek()==null){}//Queue没有isEmpty

Queue是接口,而不是和Stack一样是类,所以Queue不能创建实例,只能创建其他类,实现该接口。

Queue可以创建Linkedlist对象,Linkedlist实现了Deque(双端队列,两端都可以进出),Deque又继承了Queue;但Queue不能创建Arraylist,但是队列可以用数组进行实现。

模拟实现Queue

数组实现Queue

public class MyArrayListQueue {private int [] arr = new int[10];private int head = 0;private int tail = 0;private int size = 0;//入队public void offer(int key){if(size==arr.length){return;}arr[tail] = key;tail++;if(tail==arr.length){tail = 0;}size++;}//出队列public int poll(){if(size==arr.length){return 0;}int elem = arr[head];head++;if(head==arr.length){head = 0;}size--;return elem;}//取队列元素public int peek(){if(size==arr.length){return 0;}int elem = arr[head];return elem;}public int Front() {if(size==0){return -1;}return arr[head];}public Boolean isEmpty(){return size==0;}@Overridepublic String toString() {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("{");for (int i = 0; i < size; i++) {stringBuilder.append(arr[i]);if(i<size-1){stringBuilder.append(",");}}stringBuilder.append("}");return stringBuilder.toString();}public static void main(String[] args) {MyArrayListQueue ak = new MyArrayListQueue();ak.offer(1);ak.offer(2);ak.offer(2);ak.offer(2);System.out.println(ak);}
}

链表实现Queue

public class MyqueueLinklist {static class Node{private int val;private Node next;public Node(int val) {this.val = val;this.next = null;}
}private Node head = null;private Node tail = null;//入队列public void offer(int key){Node newnode = new Node(key);if(head==null){head = newnode;tail = newnode;}tail.next = newnode;tail = newnode;}//出队列public int poll(){if(head==null){return -1;}int p = head.val;head = head.next;if(head==null){tail=null;}return p;}public int peek(){if(head==null){return -1;}int p = head.val;return p;}public Boolean isEmpty(){return head==null;}public int size(){Node cur = head;int index = 0;for(;cur!=null;cur=cur.next){index++;}return index;}}

http://www.xdnf.cn/news/114715.html

相关文章:

  • 华为手机怎么进行音频降噪?音频降噪技巧分享:提升听觉体验
  • 【前端】【业务场景】【面试】在前端开发中,如何实现一个可拖动和可缩放的元素,并且处理好边界限制和性能优化?
  • PS Mac Photoshop 2025 for Mac图像处理 PS 2025安装笔记
  • SQL Server 2008 R2中varchar(max)的含义
  • 如何获取静态IP地址?完整教程
  • ESP32上C语言实现JSON对象的创建和解析
  • 亚马逊英国站FBA费用重构:轻小商品迎红利期,跨境卖家如何抢占先机?
  • 动态渲染页面智能嗅探:机器学习判定AJAX加载触发条件
  • Visual Studio Code 使用tab键往左和往右缩进内容
  • 差分信号抗噪声原理:
  • 编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)
  • MacOS上如何运行内网穿透详细教程
  • MySQL的图形管理工具-MySQL Workbench的下载安装及使用【保姆级】
  • 力扣 83 . 删除排序链表中的重复元素:深入解析与实现
  • [golang] 介绍 | 特点 | 应用场景
  • uniapp跨平台开发---switchTab:fail page `/undefined` is not found
  • P1217 [USACO1.5] 回文质数 Prime Palindromes【python】
  • Python - 爬虫-网页解析数据-库lxml(支持XPath)
  • 机器人新革命:Pi 0.5如何让智能走进千家万户
  • 解决yarn install 报错 error \node_modules\electron: Command failed.
  • 2025年3月电子学会青少年机器人技术(四级)等级考试试卷-实际操作
  • 【双指针】和为s的两个数字
  • STM32F407 HAL库使用 DMA_Normal 模式实现 UART 循环发送(无需中断)
  • Postman设置环境变量与Token
  • idea连接远程服务器kafka
  • 学习海康VisionMaster之顶点检测
  • Rust 数据类型
  • 【“星睿O6”AI PC开发套件评测】开箱+刷机+基础环境配置
  • wordpress学习笔记
  • Trae+DeepSeek学习Python开发MVC框架程序笔记(二):使用4个文件实现MVC框架