Java队列实现

队列定义

栈(queue)是一种先进先出(first in first out,缩写为FIFO)的线性表。

它只允许在表的一端进行插入,而在另一端删除元素。

在队列中,允许插入的一端叫队尾(rear),允许删除的一端称为队头(front)。

队的属性与方法

Java程序代码实现

public interface IMyQueue<T> {

    /*
     * 入队
     */
    boolean add(T data);

    /*
     * 出队
     */
    T poll();

    /*
     * 查看队列的第一个元素,不出队
     */
    T peek();

    /*
     * 队列长
     */
    int length();

    /*
     * 队列是否为空
     */
    boolean isEmpty();

    /*
     * 清空队列
     */
    void clear();
}

队列的顺序表示

定义

队列的顺序表示是用一组地址连续的存储单元依次存放队列中的各个元素,并用指针front指向队头,指针rear指向队尾。

代码

Java程序代码实现

import java.util.Arrays;

public class MyArrayQueue<T> implements IMyQueue<T> {

    private Object[] objs = new Object[16];

    /*
     * 队列长度
     */
    private int size;

    @Override
    public boolean add(T data) {
        if(size >= objs.length){
            addLength();
        }
        objs[size++]=data;
        return true;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T poll() {
        if(size==0){
            return null;
        }
        Object temp = objs[0];
        for(int i=0 ;i<size-1;i++){
            objs[i] = objs[i+1];
        }
        size--;
        return (T) temp;
    }

    @Override
    public int length() {
        return size;
    }

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

    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            objs[i] = null;
        }
        size=0;
    }

    /*
     * 增加数组长度
     */
    private void addLength() {
        objs = Arrays.copyOf(objs, size*3/2+1);
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("MyArrayQueue:[");
        for (int i = 0; i < size; i++) {
            sb.append(objs[i]);
            if(i != size-1){
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }

    @Override
    public T peek() {
        if(size==0){
            return null;
        }
        return (T) objs[0];
    }

}

队列的链式表示

定义

用链表表示的队列简称链队列。
一个链队列需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。
空的链队列的判决条件为头指针和尾指针均指向头节点。

代码

java程序代码实现

public class MyLinkedQueue<T> implements IMyQueue<T> {

    /*
     * 队首指针
     */
    Node<T> front;

    /*
     * 队尾指针
     */
    Node<T> rear;

    /*
     * 队列长度
     */
    private int size;

    /*
     * 重载函数
     */
    public MyLinkedQueue() {
        Node<T> node = new Node<T>(null);
        this.rear = node;
        this.front = this.rear;
        this.size = 0;
    }

    @Override
    public boolean add(T data) {
        Node<T> node = new Node<T>(data);
        rear.next = node;
        rear = node;
        size++;
        return true;
    }

    @Override
    public T poll() {
        if(size==0){
            return null;
        }
        Object temp = front.next.data;
        front = front.next;
        size--;
        return (T) temp;
    }

    @Override
    public int length() {
        return size;
    }

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

    @Override
    public void clear() {
        rear = front=null;
        size=0;
    }

    @Override
    public T peek() {
        return front.next.data;
    }

}

循环队列

定义

和顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队头到队尾的元素之外,需附设两个指针front和rear分别指示队列头元素及队列尾元素的位置。

在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置。只凭Q.front \== Q.rear无法判别队列空间是“空”还是“满”。可有两种处理方法:其一是另设一个标志位以区别队列是“空”还是“满”;其二是少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志。

循环队列空或满的判断条件

队空:Q.front \== Q.rear
队满:Q.front \== (Q.rear+1)%MAXSIZE

代码

Java程序代码实现

public class CirularQueue<T> implements IMyQueue<T> {

    /*
     * 队首下标
     */
    int front;

    /*
     * 队尾下标
     */
    int rear;

    private Object[] objs;

    public CirularQueue(){
        this(11); // 默认队列内有10个元素
    }

    public CirularQueue(int size) {
        // 队列最大长度为size个元素,保证rear转一圈之后不会和head相等
        // 也就是队列满的时候,rear+1=head,中间刚好空一个元素。当rear=head的时候,一定是队列空了
        objs = new Object[size+1]; 
        front = 0;
        rear = 0;
    }

    /*
     * 队列长度
     */
    private int size;

    @Override
    public boolean add(T data) {
        if(front == (rear+1)% (objs.length)){
            return false;
        }
        objs[rear] = data;
        rear = (rear+1)%(objs.length);
        size++;
        return true;
    }

    @Override
    public T poll() {
        if(front == rear){
            return null;
        }
        Object temp = objs[front];
        front = (front+1) % (objs.length);
        size--;
        return (T) temp;
    }

    @Override
    public T peek() {
        if(front == rear){
            return null;
        }
        return (T) objs[front];
    }

    @Override
    public int length() {
        return size;
    }

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

    @Override
    public void clear() {
        for(int i = front; i < front+size; i++){
            objs[i%(objs.length)]=null;
        }
        front = rear = 0;
        size = 0;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值