实现队列和栈

关于队列的简单介绍

队列:先进先出。数据按照a,b,c的顺序进去,也会按照a,b,c的顺序出来
在这里插入图片描述
栈:先进后出、后进先出。 弹夹形式,数据以a,b,c的形式进去,却以c,b,a的顺序出来,先进的数据会被压在栈底。
在这里插入图片描述

如何使用单链表来实现队列和栈。

队列:如果head、tail节点为null,说明此时队列中没有节点,则构建一个节点,head、tail共同指向它。如果不为null,说明队列中有节点,让上一个tail的next指向当前节点,并将当前节点作为新的tail节点

 public static class Node<V> {
        public V value;
        public Node<V> next;

        public Node(V value) {
            value = value;
            next = null;
        }
    }

    public static class MyQueue<V>{

        private Node<V> head;
        private Node<V> tail;
        private int size;

        public MyQueue(){
            head = null;
            tail = null;
            size = 0;
        }

        public boolean isEmpty(){
            return size ==0;
        }

        public int size(){
            return size;
        }

        public void offer(V value){
            Node node = new Node(value);
            if (tail == null){
                head = node;
                tail = node;
            }else{
                tail.next = node;
                tail = node;
            }
            size++;
        }

        public V poll(){
            V ans = null;
            if (head != null){
                ans = head.value;
                head = head.next;
                size --;
            }
            if (head == null){
                tail = null;
            }

            return ans;
        }

        public V peek(){
            V ans = null;
            if (head != null){
                ans = head.value;
            }
            return ans;
        }
    }

栈:比队列更加简单,只需要head一个变量即可,每次将新数据的next指向原先的老head节点,并将自己作为新的head节点

  public static class MyStack<V> {
        private Node<V> head;
        private int size;

        public MyStack() {
            head = null;
            size = 0;
        }

        public boolean isEmpty() {
            return size == 0;
        }

        public int size() {
            return size;
        }
        
        public void push(V value) {
            Node node = new Node(value);
            if (head == null) {
                head = node;
            } else {
                node.next = head;
                head = node;
            }
            size++;
        }

        public V poll() {
            V ans = null;
            if (head != null) {
                ans = head.value;
                head = head.next;
                size--;
            }
            return ans;
        }

        public V peek() {
            return head == null ? null : head.value;
        }
    }

如何使用数组实现队列和栈

用数组实现栈很简单,只需要声明index一个变量,初始值为0,每次元素增加的位置就是index处的位置,之后index++即可,取则看index是否为0,不为0代表数组中有元素。取完后index–。

public static class ArrayStack {
        private int limit;
        private int index;
        private int[] arr;

        public ArrayStack(int limit) {
            arr = new int[limit];
            index = 0;
            this.limit = limit;
        }

        public void push(int value) {
            if (index == limit) {
                throw new RuntimeException("队列已经满了");
            }

            arr[index] = value;
            index++;
        }

        public int poll() {
            int ans;
            if (index == 0) {
                throw new RuntimeException("队列为空");
            }
            ans = arr[index];
            index--;
            return ans;
        }

        public boolean isEmpty() {
            return index == 0;
        }
    }

用数组实现队列比较复杂,因为队列先进先出,如果声明takeIndex用来表示取的下标,用putIndex来表示存的下标,每次存取下标对应进行++操作的话,乍一看很方便,但如果数组中再添加新的元素呢? 如果put指针和take指针碰撞了呢?
如果take指针和put指针碰撞之后,你会发现,你不知道要取的位置有没有元素可以返回,会变得很麻烦,所以还可以额外引入一个变量,专门用来记录当前数组中元素的个数,达到彻底解耦的目的。

//数组实现队列(先进先出)
    public static class ArrayQueue {
        private int limit;
        private int takeIndex;
        private int putIndex;
        private int[] arr;
        private int size;


        public ArrayQueue(int limit) {
            this.putIndex = 0;
            this.takeIndex = 0;
            this.size = 0;
            arr = new int[limit];
            this.limit = limit;
        }

        public void push(int value) {
            if (size == limit) {
                throw new RuntimeException("队列已满");
            }
            size++;
            arr[putIndex] = value;
            putIndex = setIndex(putIndex);
        }

        public int poll(){
            if (size == 0){
                throw new RuntimeException("队列中无元素");
            }
            int ans;
            size--;
            ans = arr[takeIndex];
            takeIndex = setIndex(takeIndex);
            return ans;
        }

        public int setIndex(int i) {
            return i == limit - 1 ? 0 : i + 1;
        }
    }
在Python中实现队列可以通过内置的数据结构列表(list)来完成,也可以通过定义类来创建自己的队列。 对于实现,它是后进先出(LIFO)的数据结构,通常使用列表的append()方法来添加元素,以及pop()方法来移除最后一个添加的元素。 ```python class Stack: def __init__(self): self.items = [] def is_empty(self): return len(self.items) == 0 def push(self, item): self.items.append(item) def pop(self): if not self.is_empty(): return self.items.pop() raise IndexError("pop from empty stack") def peek(self): if not self.is_empty(): return self.items[-1] raise IndexError("peek from empty stack") def size(self): return len(self.items) ``` 对于队列实现,它是先进先出(FIFO)的数据结构,通常使用列表的append()方法来添加元素到队尾,以及pop(0)方法来移除队首的元素。 ```python class Queue: def __init__(self): self.items = [] def is_empty(self): return len(self.items) == 0 def enqueue(self, item): self.items.append(item) def dequeue(self): if not self.is_empty(): return self.items.pop(0) raise IndexError("dequeue from empty queue") def size(self): return len(self.items) ``` 在实际应用中,需要注意的是,Python列表的pop(0)操作在大数据集上效率较低,因为它需要移动列表中除第一个元素外的所有元素。在性能敏感的场合,可以考虑使用collections.deque来代替列表,因为它被优化为快速地从两端添加和移除元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值