数据结构——栈和队列(模拟实现)

目录

一:栈

[1.1: 概念](#1.1: 概念)

[1.2 :栈的使用](#1.2 :栈的使用)

1.3:栈的模拟实现

二:队列

2.1:概念

[2.2: 队列的使用](#2.2: 队列的使用)

2.3:队列的模拟实现(使用链表)

2.4:循环队列


一:栈

1.1: 概念

栈:⼀种特殊的线性表,其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。(特殊的线性表)

压栈:栈的插⼊操作叫做进栈/压栈/⼊栈,⼊数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据在栈顶。

本质上就是顺序表/链表,但是是在顺序表/链表的基础上,做出限制:

对栈来说,禁止对顺序表/链表的各种增删改查,只支持三个操作:入栈、出栈、取栈顶元素。

1.2 :栈的使用

java 复制代码
接下来我们实现一下:
package stack;  
  
import java.util.Stack;  
  
public class Tets1 {  
    public static void main(String[] args) {  
        //使用标准库的栈  
        Stack<String> stack = new Stack<>();  
        //入栈  
        stack.push("hello");  
        stack.push("world");  
        stack.push("!");  
        //取栈顶元素、peek就是查看元素但不出栈  
        //peek()方法返回栈顶元素,但不删除它  
        String top=stack.peek();  
        System.out.println(top);//!  
        //出栈(先进后出)  
        String s=stack.pop();  
        System.out.println(s);//!  
        s=stack.pop();  
        System.out.println(s);//world  
        s=stack.pop();  
        System.out.println(s);//hello  
  
    }  
}

如果栈为空 peek 和pop就会报错

1.3:栈的模拟实现

每个方法都有注释:

java 复制代码
package stack;  
  
import java.util.Arrays;  
import java.util.EmptyStackException;  
  
//模拟实现栈  
public class MyStack {  
    private String[] stack;  
    private int size;  
  
    public MyStack() {  
        stack = new String[1];  
        size = 0;  
    }  
    public MyStack(int capacity) {  
        stack = new String[capacity];  
        size = 0;  
    }  
    //扩容  
    private void resize(){  
      //创建一个更长的数组  
        String[] newStack = new String[stack.length*3];  
        //将原数组中的元素复制到新数组中  
        for(int i=0;i<stack.length;i++){  
            newStack[i] = stack[i];  
        }  
        //更新栈的引用  
        stack=newStack;  
    }  
    //入栈  
    public void push(String item){  
        if(size==stack.length){  
            //kronlei:扩容  
            resize();  
        }  
        stack[size++] = item;  
    }  
    //出栈  
    public String pop(){  
        if(size==0){  
            throw new EmptyStackException();  
        }  
        String item = stack[size-1];  
        //缩容  
        size--;  
        return item;  
    }  
    //获取栈顶元素  
    public String peek(){  
        if(size==0){  
            throw new EmptyStackException();  
        }  
        // 直接取最后一个元素  
        return stack[size-1];  
    }  
  
    @Override  
    public String toString() {  
        return "MyStack{" +  
                "stack=" + Arrays.toString(stack) +  
                ", size=" + size +  
                '}';  
    }  
  
    public static void main(String[] args) {  
        MyStack stack = new MyStack();  
        stack.push("a");  
        stack.push("b");  
        stack.push("c");  
        System.out.println(stack.toString());//MyStack{stack=[a, b, c], size=3}  
        System.out.println(stack.peek());//c  
        System.out.println(stack.pop());//c  
    }  
  
}

二:队列

2.1:概念

队列:只允许在⼀端进⾏插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)⼊队列:进⾏插⼊操作的⼀端称为队尾(Tail/Rear)出队列:进⾏删除操作的⼀端称为队头(Head/Front)

队列这样的数据结构,往往针对"耗时比较长"的操作提供辅助工作

有些操作没办法一口气全部处理完,按照顺序一个一个来,为了确保处理的顺序不乱,就把待处理的数据放到队列中。

2.2: 队列的使用

java 复制代码
注意:Queue是个接⼝,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接⼝。
package queue;  
  
import java.util.LinkedList;  
import java.util.Queue;  
  
public class Test {  
    public static void main(String[] args) {  
  
        Queue<Integer> queue = new LinkedList<>();  
        queue.offer(1);  
        queue.offer(2);  
        queue.offer(3);  
        queue.offer(4);  
        queue.offer(5);  
        System.out.println("Queue: " + queue);  
  
        System.out.println("Queuefist: " + queue.peek());  
        queue.poll();  
        System.out.println("Queue: " + queue);  
        //判定队列是否为空  
         if(queue.peek()==null)
    }  
}

2.3:队列的模拟实现(使用链表)

每个方法斗鱼注释,如果有不明白的小伙伴可以评论区奥

java 复制代码
package queue;  
//基于单链表实现队列  
public class MyQueue {  
    static class Node {  
        public String val;  
        public Node next;  
  
        public Node(String val) {  
            this.val = val;  
            this.next = null;  
        }  
    }  
  
    private Node head = null;  
    private Node tail = null;  
  
    //基于链表实现队列  
    //入队-》尾插  
    public void offer(String val) {  
    Node newNode = new Node(val);  
    if(head==null){  
        head=tail=newNode;  
        return ;    }else{  
  
        tail.next=newNode;  
        //尾插之后,更新tail  
        tail=newNode;  
    }  
    }  
  
    //出队-》头删  
    public String poll() {  
        if(head==null){  
            return null;  
        }  
        //保存头节点的值  
        //接下来把这个值删掉,需要返回这个值  
        String val=head.val;  
        head=head.next;  
        if(head==null){  
            //如果头节点已经是最后一个节点,则更新tail  
            tail=null;  
        }  
        return val;  
    }  
  
    //查看队首元素  
    public String peek() {  
        if(head==null){  
            return null;  
        }else{  
            //直接返回头节点的值  
            return head.val;  
        }  
    }  
    public boolean isEmpty(){  
        return head==null;  
    }  
    public int size() {  
      int  size=0;  
      for(Node cur=head;cur!=null;cur=cur.next){  
          size++;  
      }  
      return size;  
    }  
    public static void main(String[] args) {  
          MyQueue queue=new MyQueue();  
          queue.offer("a");  
          queue.offer("b");  
          queue.offer("c");  
          System.out.println(queue.peek());//查看队首元素  
          System.out.println(queue.poll());//出队  
          System.out.println(queue.peek());//查看队首元素  
          System.out.println(queue.poll());//出队  
          System.out.println(queue.peek());//查看队首元素  
          System.out.println(queue.poll());//出队  
          System.out.println(queue.peek());//查看队首元素  
          System.out.println(queue.isEmpty());//判断是否为空  
    }  
}

2.4:循环队列

实际中我们有时还会使⽤⼀种队列叫循环队列。如操作系统课程讲解⽣产者消费者模型时可以就会使⽤循环队列。环形队列通常使⽤数组实现

这个我们就使用数组表达,有一个head和tail(头和尾),每次加入元素或者出队列。就可以加加减减,然后创建一个size表示元素个数,如果size==0,那就空了。具体看看代码:

java 复制代码
package queue;  
  
public class MyQueueByArray {  
    //数组实现队列  
    public String[] arr=null;  
    //队首  
    public int head=0;  
    //队尾  
    public int tail=0;  
    //元素个数  
    public int size=0;  
    public MyQueueByArray(){  
        arr=new String[10000];  
    }  
    public MyQueueByArray(int capacity){  
        arr=new String[capacity];  
}  
//入队列  
    public void offer(String val){  
        if (size==arr.length){  
            return ;  
        }else{  
            //把新的元素放到tail位置  
            arr[tail]=val;  
            //tail后移  
            tail++;  
            //为构成环形队列,当tail==arr.length时,重新回到0  
            if(tail==arr.length){  
                tail=0;  
            }  
            //元素个数+1  
            size++;  
        }  
    }  
    //出队列  
    public String poll() {  
        if (size == 0) {  
            return null;  
        }  
            //取队首元素  
            String value = arr[head];  
            //head后移  
            head++;  
            //为构成环形队列,当head==arr.length时,重新回到0  
            if (head == arr.length) {  
                head = 0;  
            }  
            //更新元素个数  
            size--;  
        return value;  
    }  
    //查看队首元素  
    public String peek(){  
        if(size==0){  
            return null;  
        }  
        return arr[head];  
    }  
    //判断队列是否为空  
    public Boolean isEmpty(){  
        return size==0;  
    }  
  
    public static void main(String[] args) {  
        MyQueueByArray queue=new MyQueueByArray();  
        queue.offer("a");  
        queue.offer("b");  
        queue.offer("c");  
        System.out.println(queue.peek());  
        System.out.println(queue.poll());  
        System.out.println(queue.poll());  
        System.out.println(queue.poll());  
    }  
}

注释还是很详细的,看不懂可以评论哦

相关推荐
字节高级特工2 小时前
网络协议分层与Socket编程详解
linux·服务器·开发语言·网络·c++·人工智能·php
祈祷苍天赐我java之术2 小时前
Redis 热点数据与冷数据解析
java·redis·mybatis
大飞pkz3 小时前
【设计模式】访问者模式
开发语言·设计模式·c#·访问者模式
9号达人3 小时前
Java20 新特性详解与实践
java·后端·面试
rufeii3 小时前
php-cve篇(CVE-2019-11043&CVE-2012-1823)
开发语言·php
sniper_fandc3 小时前
关于Mybatis-Plus的insertOrUpdate()方法使用时的问题与解决—数值精度转化问题
java·前端·数据库·mybatisplus·主键id
QQ12958455043 小时前
Mac添加全局变量
开发语言·macos
天若有情6734 小时前
Spring配置文件XML验证错误全面解决指南:从cvc-elt.1.a到找不到‘beans‘元素声明
xml·java·spring
郝学胜-神的一滴4 小时前
Effective STL 第1条:慎重选择容器类型
开发语言·c++·程序人生·软件工程