数据结构与算法之队列

 

目录

链式队列:

顺序队列(循环队列):

队列的使用:


队列是一种只允许在一端插入数据(队尾),在另一端删除数据(队头)的操作的特殊线性表。

队列的特点:先进先出

队列可以用数组实现,称为顺序队列,又叫循环队列。也可以用链表实现,称为链式队列。

链式队列:

入队头插:O(1), 出队队尾出:O(n)[出队不知道队尾的前驱]

入队尾插:O(n),出队队头出:O(1)

若想要入队和出队的时间复杂度都为O(1),则需要另外定义一个变量,永远指向队尾。

 

package queue.com;

public class MyListQueue {
    class Node {
        int data;
        Node next;

        public Node(int data) {
            this.data = data;
        }
    }
    Node front;
    Node rear;
    int usedSize;

    //判断是否为空
    public boolean isEmpty() {
        return usedSize == 0;
    }

    // 入队(尾插)
    public void offer(int data) {
        Node node = new Node(data);
        if (isEmpty()) {
            this.front = node;
            this.rear = node;
        } else {
            this.rear.next = node;
            this.rear = node;
        }
        this.usedSize++;
    }

    //出队(从头出)
    public int poll() {
        int tmp = this.front.data;
        this.front = this.front.next;
        this.usedSize--;
        return tmp;
    }

    //弹出队头元素
    public int peek() {
        return this.front.data;
    }
 }

顺序队列(循环队列):

为啥要把队列设置为循环的呢??空间的可利用效率达到最高!

队头:front

队尾:rear 当前可以存放数据元素的下标

因为front和rear相遇有可能是空的,也有可能是满的。因此我们规定front和rear相遇的时候队列是空的,判断为满:牺牲一定的空间,如果我们要放8个元素,放入7个元素就认为队列已经满了。如果要放第8个元素的时候,先判断(rear+1)%length是否等于front:若相等,则满。

 

package queue.com;

public class MyCircularQueue {

        public int[] elem;
        public int front;
        public int rear;
        public int usedSize;
        public MyCircularQueue(int k) {
            this.elem = new int[k+1];
            this.front = 0;
            this.rear = 0;
            this.usedSize = 0;
        }
        //进队列
        public boolean enQueue(int value) {
          if (isFull()) {
              return false;
          }
          this.elem[rear] = value;
          this.rear = (this.rear + 1) % this.elem.length;
          this.usedSize++;
          return true;
        }
        //出队列
        public boolean deQueue() {
            if (isEmpty()) {
                return false;
            }
            this.front = (this.front+1) % this.elem.length;
            this.usedSize--;
            return true;
        }
        //弹出队头元素
        public int Front() {
            if(isEmpty()) {
                return -1;
            }
            return this.elem[this.front];
        }
        //弹出队尾元素
        public int Rear() {
            if(isEmpty()) {
                return -1;
            }
            int index = this.rear == 0 ? index = this.elem.length-1 : this.rear-1;
            return elem[index];
        }

        public boolean isEmpty() {
            return this.front == this.rear;
        }

        public boolean isFull() {
            return this.front == (this.rear+1)%this.elem.length;
        }

}

Java中的队列:

public static void main(String[] args) {
    Queue<Integer> queue = new LinkedList<>();
    queue.add(1); //入队列  [抛出异常]
    queue.offer(1); //入队列 [返回特殊值]
    queue.remove(); //出队列 [抛出异常]
    queue.poll(); // 出队列 [返回特殊值]
    queue.element(); //队首元素 [抛出异常]
    queue.peek(); //队首元素 [返回特殊值]
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值