数据结构 队列(JAVA语言描述)

数据结构 队列(JAVA语言描述)

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(First In First Out)的线性表。允许插入的一端称为队尾,允许删除的一端称为队头。
队头(Front):允许删除的一端,又称队首。
队尾(Rear):允许插入的一端。
空队列:不包含任何元素的空表。

  • 队列的常见方法
public interface Queue<E> extends Iterable<E> {
    public void offer(E element);//入队
    public E poll();//出队
    public E element();
    public boolean isEmpty();
    public void clear();
    public int size();
}
  • 队列方法的实现
public class ArrayQueue<E> implements Queue<E> {
    private ArrayList<E> list;
    public ArrayQueue(){
        list = new ArrayList<>();
    }

    @Override
    public void offer(E element) {
        list.add(list.size(),element);
    }

    @Override
    public E poll() {
        return list.remove(0);
    }

    @Override
    public E element() {
        return list.get(0);
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

    @Override
    public String toString() {
        return list.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (null == o) return true;
        if (this==o){
            return true;
        }
        if (o instanceof  ArrayQueue){
            ArrayQueue other = (ArrayQueue) o;
            return list.equals(other.list);
        }
        return false;
    }

关于线性表的方法具体实现

  • 用队列去实现栈
class StackImplByQueue<E> implements Stack<E>{
    private ArrayQueue<E> queue1;
    private ArrayQueue<E> queue2;
    public StackImplByQueue(){
        queue1 = new ArrayQueue<>();
        queue2= new ArrayQueue<>();
    }

    @Override
    public int size() {
        if (queue1.isEmpty()&&queue2.isEmpty()){
            return 0;
        }else if (!queue1.isEmpty()){
            return queue1.size();
        }else {
            return queue2.size();
        }
    }

    @Override
    public boolean isEmpty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }

    @Override
    public void push(E element) {
            if(queue1.isEmpty() && queue2.isEmpty()){
                queue1.offer(element);
            }else if (!queue1.isEmpty()){
                queue1.offer(element);
            }else {
                queue2.offer(element);
            }
   }

    @Override
    public E pop() {
           if (isEmpty()){
               return null;
           }
           E ret = null;
           if (!queue1.isEmpty()){
                while (queue1.size()!=1){
                    queue2.offer(queue1.poll());
                }
                ret = queue1.poll();
           }else {
               while (queue2.size()!=1){
                   queue1.offer(queue2.poll());
               }
               ret = queue2.poll();
           }
           return ret;
    }

    @Override
    public E peek() {
        if (isEmpty()){
            return null;
        }
        E ret = null;
        if (!queue1.isEmpty()){
            while (queue1.size()!=1){
                queue2.offer(queue1.poll());
            }
            ret = queue1.poll();
            queue2.offer(ret);
        }else {
            while (queue2.size()!=1){
                queue1.offer(queue2.poll());
            }
            ret = queue2.poll();
            queue1.offer(ret);
        }
        return ret;
    }

    @Override
    public void clear() {
            queue1.clear();
            queue2.clear();
    }

    @Override
    public Iterator<E> iterator() {
        if (isEmpty()){
            return queue1.iterator();
        }else if (!queue1.isEmpty()){
            return queue1.iterator();
        }else {
            return queue2.iterator();
        }
    }

    @Override
    public String toString() {
        if (isEmpty()){
            return "[]";
        }else if (!queue1.isEmpty()){
            return queue1.toString();
        }else {
            return queue2.toString();
        }
    }
  • 循环队列

将队列臆造成一个环状的空间,即把存储队列元素的表从按逻辑上视为一个环,称为循环队列。当队首指针 Q.front == MAXSIZE - 1,再前景一个位置就自动到0,这可以利用除法取余运算(%) 来实现。

队首指针进1:Q.front = (Q.front + 1) % MAXSIZE;
队尾指针进1:Q.rear = (Q.rear + 1)% MAXSIZE;
队列长度:(Q.front + MAXSIZE - Q.rear) % MAXSIZE;

//循环队列
public class ArrayLoopQueue<E> implements Queue<E> {
    private E[] data;
    //队首
    private int front;
    //队尾
    private  int rear;
    //元素个数
    private int size;
    //默认容量
    private static int DEFAULT_CAPACITY=10;
    public ArrayLoopQueue(){
        data = (E[]) new Object[DEFAULT_CAPACITY+1];
        front =0;
        rear =0;
        size =0;
    }
    @Override
    public void offer(E element) {
        //判满
        if ((rear+1)% data.length == front){
            resize(data.length*2-1);
        }
        data[rear] = element;
        rear= (rear+1)%data.length;
        size++;
    }

    @Override
    public E poll() {
        //判空
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        E ret = data[front];
        front = (front+1)% data.length;
        size--;
        if (size <= (data.length-1)/4&& data.length-1>DEFAULT_CAPACITY){
            resize(data.length/2+1);
        }
        return null;
    }

    private void resize(int newLen) {
        E[] newdata = (E[]) new Object[newLen];
        int index=0;
        for(int i = front;i!=rear;i=(i+1)% data.length){
            newdata[index++]=data[i];
        }
        data = newdata;
        front = 0;
        rear  = index;
    }

    @Override
    public E element() {
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        return data[front];
    }

    @Override
    public boolean isEmpty() {
        return front == rear;
    }

    @Override
    public void clear() {
            data = (E[]) new Object[DEFAULT_CAPACITY];
        front =0;
        rear =0;
        size =0;
    }

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

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()){
            sb.append(']');
            return sb.toString();
        }else {
            for (int i =front;i!=rear;i=(i+1)% data.length){
                sb.append(data[i]);
                if ((i+1)% data.length==rear){
                    sb.append(']');
                }else{
                    sb.append(',');
                }
            }
        }
        return  sb.toString();
    }

    @Override
    public boolean equals(Object o) {
                if (o == null) return false;
                if (this == o) return true;
                if (o instanceof  ArrayLoopQueue){
                    ArrayLoopQueue<E> other = (ArrayLoopQueue<E>) o;
                    if (size != other.size){
                        return false;
                    }
                    int i =front;
                    int j =other.front;
                    while (i!=rear){
                        if (!data[i].equals(other.data[j])){
                            return false;
                        }
                        i = (i+1)% data.length;
                        j = (j+1)% other.data.length;
                    }
                    return true;
                }
                return false;
    }
    @Override
    public Iterator<E> iterator() {
        return new ArrayLoopQueueIterator();
    }
    class ArrayLoopQueueIterator implements Iterator<E>{
        private  int cur = front;
        @Override
        public boolean hasNext() {
            return cur!=rear;
        }

        @Override
        public E next() {
            E ret = data[cur];
            cur = (cur+1)% data.length;
            return ret;
        }
    }
}
  • 双端队列

双端队列(Deque:double ended queue)就是一个两端都是结尾的队列。
队列的每一端都能够插入数据项和移除数据项。
相对于普通队列,双端队列的入队和出队操作在两端都可进行。

public class ArrayDeque<E> implements Dequeue<E>, Stack<E> {
    private E[] data;
    private int front;
    private int rear;
    private int size;
    private static int DEFAULT_CAPACITY=10;
    public ArrayDeque(){
        data = (E[]) new Object[DEFAULT_CAPACITY+1];
        front =0;
        rear =0;
        size =0;
    }
    @Override
    public void addFirst(E element) {
        if ((rear+1)% data.length ==front){
            resize(data.length*2-1);
        }
        front =(front-1+ data.length)% data.length;
        data[front] = element;
        size++;
    }

    private void resize(int newLen) {
        E[] newdata = (E[]) new Object[newLen];
        int index=0;
        for(int i = front;i!=rear;i=(i+1)% data.length){
            newdata[index++]=data[i];
        }
        data = newdata;
        front = 0;
        rear  = index;
    }

    @Override
    public void addLast(E element) {
        if ((rear+1)% data.length ==front){
            resize(data.length*2-1);
        }
        data[rear] =element;
        rear =(rear+1)% data.length;
        size++;
    }

    @Override
    public E removeFirst() {
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        E ret = data[front];
        front =(front-1)% data.length;
        size--;
        if (size<= (data.length-1)/4 && data.length-1 >DEFAULT_CAPACITY){
            resize(data.length/2+1);
        }
        return ret;
    }

    @Override
    public E removeLast() {
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        rear =(rear-1+ data.length)% data.length;
        E ret = data[rear];
        size--;
        if (size<= (data.length-1)/4 && data.length-1 >DEFAULT_CAPACITY){
            resize(data.length/2+1);
        }
        return ret;
    }

    @Override
    public E getFirst() {
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        return data[front];
    }

    @Override
    public E getLast() {
        if (isEmpty()){
            throw new IllegalArgumentException("null");
        }
        return data[(rear-1+ data.length)% data.length];
    }

    @Override
    public void offer(E element) {
            addLast(element);
    }

    @Override
    public E poll() {
        return removeFirst();
    }

    @Override
    public E element() {
        return getFirst();
    }

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

    @Override
    public void push(E element) {
        addLast(element);
    }

    @Override
    public E pop() {
        return removeLast();
    }

    @Override
    public E peek() {
        return getLast();
    }

    @Override
    public void clear() {
        data = (E[]) new Object[DEFAULT_CAPACITY];
        front =0;
        rear =0;
        size =0;
    }

    @Override
    public int size() {
        return size;
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()) {
            sb.append(']');
            return sb.toString();
        }
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            sb.append(data[i]);
            if ((i + 1) % data.length == rear) {
                sb.append(']');
            } else {
                sb.append(',');
                sb.append(' ');
            }
        }
        return sb.toString();
    }
    @Override
    public Iterator<E> iterator() {
        return new ArrayDequeIterator();
    }

    class ArrayDequeIterator implements Iterator<E> {
        private int cur = front;

        @Override
        public boolean hasNext() {
            return cur != rear;
        }

        @Override
        public E next() {
            E ret = data[cur];
            cur = (cur + 1) % data.length;
            return ret;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值