---栈&队列---

本文详细介绍了栈和队列这两种基本数据结构,包括它们的概念、核心操作以及如何使用顺序表和链表进行实现。栈遵循后进先出原则,常用操作有入栈、出栈和取栈顶元素;队列则遵循先进先出,涉及的操作有入队、出队和查看队首元素。此外,还讨论了栈和队列的复杂应用,如优先队列、消息队列和阻塞队列。通过示例代码,读者可以深入理解这两种数据结构的内部工作机制。
摘要由CSDN通过智能技术生成

目录

栈(Stack)

一、概念

二、栈的核心操作:

三、栈的实现:

1.使用顺序表实现栈

2.使用链表实现栈

队列(Queue)

一、概念

二、复杂队列举例:

三、队列的实现

1.使用链表实现队列

2.使用数组实现环形队列


栈(Stack)

一、概念

中的元素遵循“后进先出”,允许进行插入删除的那一端称为栈顶;固定的,不允许进行插入和删除的另一端称为栈底,可以把它想象成枪上的弹夹方便理解。同时Stack是一个类,可以拿来直接用。

二、栈的核心操作:

①入栈:把元素放到栈里面,push()

②出栈:把最后进来的元素删掉,pop()

③取栈顶元素:获取最后一进来的元素的结果,peek()

三、栈的实现:

1.使用顺序表实现栈

private int[] data=new int[100];
    private int size=0;

a)尾插 → 入栈

public void push(int val){
        if (size>=data.length){
            return;
        }
        data[size]=val;
        size++;
    }

b)尾删 → 出栈

public Integer pop(){
        if (size==0){
            return null;
        }
        //栈顶元素就是最后一个元素
        int ret=data[size-1];
        size--;
        return ret;
    }

c)根据下标取元素 → 取栈顶元素

public Integer peek(){
        if (size==0){
            return null;
        }
        return data[size-1];
    }

2.使用链表实现栈

定义节点

class Node{
    int val;
    Node next;
    public Node(int val) {
        this.val = val;
    }
}

(此处使用不带傀儡结点的链表来表示)

a)头插 → 入栈

public void push(int val){
            Node newNode=new Node(val);
            //把新结点进行头插
            //由于当前链表不带傀儡结点,所以先判断是否为空
            if (head==null){
                head=newNode;
                return;
            }
            newNode.next=head;
            head=newNode;
        }

b)头删 → 出栈

public Integer pop(){
            //进行头删
            if (head==null){
                return null;
            }
            if (head.next==null){
                int ret= head.val;
                head=null;
                return ret;
            }
            int ret=head.val;
            head =head.next;
            return ret;
        }

c)取头节点 → 取栈顶元素

public Integer peek(){
                if (head==null){
                    return null;
                }
                return head.val;
            }

队列(Queue)

一、概念

队列中的元素遵循“先进先出”,允许删除的一端称为队首,允许插入的一端称为队尾

和栈不同,队列是一个接口,不能直接实例化,需要创建对应的子类。

二、复杂队列举例:

1.优先队列

2.消息队列(队列中的元素带有类型,出队列的时候可以按照类型来取元素)

3.阻塞队列(如果队列满,此时继续插入数据,就会形成“阻塞”,如果队列为空,此时继续取元素也会形成“阻塞”【阻塞:通俗来讲就是代码不会继续往下走】)

4.无锁队列(更高效的线程安全的队列,保证线程安全的常见手段是加锁,但是加锁效率比较低)

三、队列的实现

1.使用链表实现队列

定义结点

static class Node{
        int val;
        Node next;
        public Node(int val){
            this.val=val;
        }
    }

创建链表的头结点和尾结点

private Node head=null;
    private Node tail=null;

a)入队列 offer(int val)

public boolean offer(int val){
        Node newNode=new Node(val);
        //插入到链表尾部,需要考虑当前列表是否为空
        if (head==null){
            //直接让head和tail指向新结点即可
            head=newNode;
            tail=newNode;
            return true;
        }
        tail.next=newNode;
        tail=tail.next;
        return true;
    }

b)出队列 poll()

public Integer poll() {
        if (head==null){
            return null;
        }
        int ret=head.val;
        if (head.next==null){
            head=null;
            return ret;
        }
        head=head.next;
        return ret;
        }

c)取队首元素  peek(int val)

public Integer peek(){
        if (size==0){
            return null;
        }
        return data[size-1];
    }

2.使用数组实现环形队列

创建俩个下标,分别表示队列的头部和尾部,专门设一个size变量记录,size==0为空,size==数组长度为满。

private int[] data=new int[100];
    //队列有效区间[head,tail)
    private int head=0;
    private int tail=0;
    private int size=0;

a)入队列

public boolean offer(int val){
        if (size==data.length){
            //队列满了,此处也可以实现扩容逻辑
            return false;
        }
        //把新元素放到tail对应的下标上
        data[tail]=val;
        tail++;
        //tail到达了数组末尾,就需要让tail从头开始
        if (tail==data.length){
            tail=0;
        }
        size++;
        return true;
    }

b)出队列

public Integer poll(){
        if (size==0){
            return null;
        }
        int ret=data[head];
        head++;
        if (head==data.length){
            head=0;
        }
        size--;
        return ret;
    }

c)取队首元素

public Integer peek(){
        if (size==0){
            return null;
        }
        return data[head];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值