数据结构--队列(java)

版权声明:本文为博主原创文章,禁止一切形式的转载,爱程序员网你自觉点。 https://blog.csdn.net/c601097836/article/details/49883607

队列是一种先进先出的数据结构

队列上的插入操作叫入队列,删除操作叫出队列

队列有对头,和队尾

就想超市结账排队一样,顾客总是排到队列的尾部(队尾),也就是说在队列的尾部入队列,队列的头部出队列。

如何在java中实现队列有两种选择,一种是通过数组实现,一种是通过链表实现

数组实现的队列:

//队列接口
interface Queue<T>{
    boolean enQueue(T k);
    T deQueue();

    boolean isEmpty();

    void clear();

    int length();
}

//顺序队列
class ArrayLinerQueue<T> implements Queue<T>{

    private int size=0;
    private int head=0;
    private int tail=0;
    private Object[] data = new Object[4];

    @Override
    public boolean enQueue(T k) {
        // 判断是否需要进行数组扩容
        if (tail >= data.length) {
            resize();
        }
        System.out.println("enQueue: " + k);
        data[tail++] = k;
        size++;
        return true;
    }
    /**
     * 数组扩容
     */
    private void resize() {
        System.out.println("数组空间不够,扩容");
        Object[] temp = new Object[data.length * 2];
        for (int i = head; i < tail; i++) {
            temp[i] = data[i];
            data[i] = 0;
        }
        data = temp;
    }
    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        System.out.println("deQueue:"+(T)data[head]);
        size--;
        return  (T)data[head++];
    }

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

    @Override
    public void clear() {
        // 将数组中的数据置为null, 方便GC进行回收
        for (int i = 0; i < size; i++) {
            data[size] = null;
        }
        size = 0;
        head=0;
        tail=0;
    }

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

    @Override
    public String toString() {
        return "ArrayQueue{" +
                "size=" + size +
                ", head=" + head +
                ", tail=" + tail +
                ", data=" + Arrays.toString(data) +
                '}';
    }
}

//顺序循环队列
class ArrayCycleQueue<T> implements Queue<T>{

    private int size=0;
    private int head=0;
    private int tail=0;
    private Object[] data = new Object[4];

    @Override
    public boolean enQueue(T k) {
        // 判断是否需要进行数组扩容
        if (head==tail && head!=0) {
            resize();
        }
        if (tail>=data.length && head>0){
            tail=0;
        }
        System.out.println("enQueue: " + k);
        data[tail++] = k;
        size++;
        return true;
    }
    /**
     * 数组扩容
     */
    private void resize() {
        System.out.println("数组空间不够,扩容");
        Object[] temp = new Object[data.length * 2];
        for (int i = head+data.length; i < temp.length; i++,head++) {
            temp[i] = data[head];
        }
        for (int i = 0; i < tail; i++) {
            temp[i] = data[i];
        }

        data = temp;
    }
    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        System.out.println("deQueue:"+(T)data[head]);
        size--;
        return  (T)data[head++];
    }

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

    @Override
    public void clear() {
        // 将数组中的数据置为null, 方便GC进行回收
        for (int i = 0; i < size; i++) {
            data[size] = null;
        }
        size = 0;
        head=0;
        tail=0;
    }

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

    @Override
    public String toString() {
        return "ArrayQueue{" +
                "size=" + size +
                ", head=" + head +
                ", tail=" + tail +
                ", data=" + Arrays.toString(data) +
                '}';
    }
}

链表实现的队列


//链表实现队列
class LinkedListQueue<T> implements Queue<T>{

    private int size=0;
    private QueueNode head=null;
    private QueueNode tail=null;

    @Override
    public boolean enQueue(T k) {

        System.out.println("enQueue: " + k);
        QueueNode queueNode = new QueueNode();
        queueNode.setData(k);

        if (tail==null){
            tail=queueNode;
            head=tail;
        }else {
            tail.setNext(queueNode);
            tail=queueNode;
        }
        size++;
        return true;
    }

    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        T tempdata = head.getData();
        head=head.getNext();
        System.out.println("deQueue:"+tempdata);
        size--;
        return  tempdata;
    }

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

    @Override
    public void clear() {
        size = 0;
        head=null;
        tail=null;
    }

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

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();

        QueueNode temp = head;
        while (temp!=null){
            sb.append(temp.getData()+" ");
            temp=temp.getNext();
        }
        return "LinkedListQueue{" +
                "size=" + size +
                ", head=" + head.getData() +
                ", tail=" + tail.getData() +
                ", queue="+sb.toString()+
                '}';
    }

    private class QueueNode{
        private T data;
        private QueueNode next;

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public QueueNode getNext() {
            return next;
        }

        public void setNext(QueueNode next) {
            this.next = next;
        }
    }

}

测试

package com.zq.datastruct.linkedlist;

import java.util.Arrays;

/**
 * Created by zhengshouzi on 2015/11/16.
 */
public class QueueTest {
    public static void main(String[] args) {
        Queue<Integer> queue =null;

        System.out.println("------------------------arrayLinerQueue-------------------------------------");

        queue=new ArrayLinerQueue();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);
        System.out.println(queue.toString());
        queue.enQueue(444);

        System.out.println(queue.toString());

        System.out.println("------------------------arrayCycleQueue-------------------------------------");

       queue = new ArrayCycleQueue<>();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);
        System.out.println(queue.toString());
        queue.enQueue(567);
        queue.enQueue(1200);

        System.out.println(queue.toString());



        System.out.println("------------------------linkedListQueue-------------------------------------");

       queue = new LinkedListQueue();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);

        System.out.println(queue.toString());
        queue.enQueue(567);
        queue.enQueue(1200);

        System.out.println(queue.toString());

    }
}

这里写图片描述



队列应用:

当多个任务分配给打印机时,为了防止冲突,创建一个队列,把任务入队,按先入先出的原则处理任务。
当多个用户要访问远程服务端的文件时,也用到队列,满足先来先服务的原则。
现如今众多的消息中间件的实现就是采用队列的思想。
……
有一个数学的分支,叫队列理论(queuing theory )。用来计算 预测用户在队中的等待时间,队的长度等等问题。
答案取决于用户到达队列的频率,用户的任务的处理时间。如果比较简单的情况,可以单单用分析解决。一个简单的例子就是,
一部电话,一个接线员。当一个电话打进来,如果接线员很忙,就电话放到等待线路后。接线员从队头开始应答。
凡事一切需要按照顺序来处理的数据,都可以用队列来实现,如果顺序带有优先级,可以用优先队列

扫描二维码关注公众号,回复: 3793790 查看本文章

队列和栈的说明:

队列比较适合于用链表实现:因为队列的操作在队列的两端进行,使用数组不方便

栈比较适合于用数组实现:而栈的操作始终在栈顶进行,始终在数组顶部操作就好了。

猜你喜欢

转载自blog.csdn.net/c601097836/article/details/49883607