栈和队列的实现

目录

栈(Stack)

队列(Queue)

循环队列

队列实现栈

栈实现队列


栈(Stack)

栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈的数据元素遵循先进后出的原则。

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

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

栈遵循先进后出的原则,那出栈顺序为: 56  45   34   23   12。

队列(Queue)

队列:只允许在一端进行数据插入数据的操作,在另一端进行删除数据操作的特殊线性表。队列具有先进先出的原则。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

队列具有先进先出的原则,则出队的顺序为: 12 23 34 45 56。

队列的方法:

用单链表模拟实现队列:

队列具有先进先出的原则,我们入队的时候采用尾插法,出队的时候采用头删法。

public class MyQueue {

    static class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = this.val;
        }
    }
    public Node head;
    public Node last;
    public int usedSize;

    /**
     * 入队
     * 使用尾插法
     */
    public void offer(int val) {
        Node node = new Node(val);
        if(head == null) {
            head = node;
            last = node;
        } else {
            last.next = node;
            last = node;
        }
        usedSize++;
    }

    /**
     * 出队
     */
    public int pool() {
        if(empty()) {
            throw new EmptyException("队列为空");
        }
        int ret = head.val;
        head = head.next;
        if(head == null) {
            last = null;//只有一个节点,last也要置空
        }
        usedSize--;
        return ret;
    }
    public boolean empty() {
        return usedSize == 0;
    }

    /**
     * 获取队头元素
     */
    public int peek() {
        if(empty()) {
            throw new EmptyException("队列为空");
        }
        return head.val;
    }
    public int getUsedSize() {
        return usedSize;
    }
}

循环队列

当数组前面几个元素被删除,后面又已经满了的时候如何向数组插入元素?

public class MyCircularQueue {
    private int[] elem;
    private int front; // 队头
    private int rear;  // 队尾

    public MyCircularQueue(int k) {
        this.elem = new int[k+1];
    }
    /**
     * 入队
     */
    public boolean enQueue(int val) {
        if(isFull()) {
            return false;
        }
        elem[rear] = val;
        rear = (rear+1) % elem.length;
        return true;
    }


    /**
     * 队列是否为满
     */
    public boolean isFull() {
        return (rear + 1) % elem.length == front;
    }

    /**
     * 出队
     */
    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        front = (front+1) % elem.length;
        return true;
    }
    /**
     * 得到队头元素
     */
    public int Front() {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    /**
     * 得到队尾元素
     */
    public int rear() {
        if(isEmpty()) {
            return -1;
        }
        int index = (rear == 0) ? elem.length-1 : rear-1;
        return elem[index];
    }
    /**
     * 是否为空
     */
    public boolean isEmpty() {
        return front == rear;
    }
}

队列实现栈

具体问题是用两个队列实现一个先进后出的栈,并且实现栈的push(),peek(),pop()和empty().

思路解析:

整体思路:

入栈:对两个队列进行检查, 入不为空的队列,若都为空则如qu1队列

出栈: 不为空的队列出size-1个元素到另外一个空队列里面去

将qu1里的元素取出来接可以了

获取栈顶元素

获取栈顶元素,需要将不为空的队列全部移到另外一个队列里面,每移出一个元素都用val记录,当最后一个元素移出来,val的值就是栈顶元素的值

public int top() {
        if(empty()) {
            return -1;//两个队列都为空,意味着当前的栈为空
        }
        if(!qu1.isEmpty()) {
            int size = qu1.size();
            int val = -1;
            for (int i = 0; i < size; i++) {
                val = qu1.poll();
                qu2.offer(val);
            }
            return val;
        }else {
            int size = qu2.size();
            int val = -1;
            for (int i = 0; i < size; i++) {
                val = qu2.poll();
                qu1.offer(val);
            }
            return val;
        }
    }

判断是否为空

当qu1和qu2都为空的时候,队列就为空

栈实现队列

具体问题是用两个栈实现一个先进先出的队列,并实现队列的push(),pop(),peek(),empty()方法。

思路解析:

入队列: 将元素放到s1栈里面

出队列:首先检查s2的栈是否为空,若为空,将s1的元素先出栈,然后入到s2里面,s2的栈顶元素就是要出队列的元素.若两个栈都为空,则队列为空.

获取队头元素:思路和出队列类似,在最后一步直接获取s2的对头元素就可以.

判断是否为空:若s1和s2都为空,则队列为空

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值