利用数组实现双向队列(JAVA源码)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011350550/article/details/83210795

本文的主要内容就是利用数组[]实现双向队列,当然,Java中有比较丰富的容器可以直接使用,实现类似的功能容器有助于我们更深入的学习好了解相关知识。
现在就开始一步一步讲解如何实现。

1、双向队列的功能
首先,我们既然要实现该功能,就必然要把需求梳理清楚,我们要实现的容器到底有哪些功能。我们实现的队列主要功能如下:

入队列(push)
出队列(pop)
队首入队列(unshift)
队首出队列(shift)
获取队列中某个元素(get)
将值插入队列某个位置(insert)
移除队列中指定位置的值(remove)
迭代器(iterator) 所以,我们可以定义队列的接口如下:

package LinearList;

import java.util.Iterator;

public interface LinearList<E> {
    //获取队列指定位置元素
    public E get(int i);

   //获取队列长度
    public int getSize();
    
    //判断队列是否为空
    public boolean isEmpty();
    
    //队列指定位置插入元素
    public boolean insert(int i, E o);
    
    //移除指定位置元素
    public boolean remove(int i);
    
    //队尾入队列
    public boolean push(E o);
    
    //队首入队列
    public boolean unshift(E o);
    
    //队尾出队列
    public E pop();

    //队首出队列
    public E shift();
    
    //迭代器
    public Iterator<E> iterator();
}

定义了一个泛型接口,方法含义已在代码中注释,不解释了。 下面就贴出具体实现类,并解释其含义。

package LinearList.imp;

import LinearList.*;
import com.sun.istack.internal.NotNull;
import java.util.*;

/**
 * 数组实现线性表
 * author: xubaodian
 * time: 2018/9/25
 * @param
 */
public class ArrayLinearList<E> implements LinearList<E> {

    //采用数组实现队列,初始数组长度为8,
    private int Len = 8;

    //队列长度,队列长度小于等于数据长度
    private int count = 0;

    //数组,是队列的容器,用来保存队列元素
    private Object []arrayList;


    public ArrayLinearList() {
        arrayList = new Object[this.Len];
    }

    //获取队列中的指定元素,若索引大于队列长度,则抛出异常
    @Override
    public E get(int i) {
        if (i < this.count) {
            return (E)this.arrayList[i];
        } else {
            throw new ArrayIndexOutOfBoundsException("索引超出队列长度");
        }
    }

    //获取队列长度
    @Override
    public int getSize() {
        return this.count;
    }

    //判断队列是否为空
    @Override
    public boolean isEmpty() {
        if (this.count == 0) {
            return  true;
        }
        return false;
    }

    //队列指定位置插入元素
    @Override
    public boolean insert(int i, E o) {
        if (i <= this.count) {
            for(int j = this.count; j > i ; j--) {
                this.arrayList[j] = this.arrayList[j - 1];
            }
            this.arrayList[i] = o;
            this.count++;
            this.expandArray();
            return true;
        } else {
            throw new ArrayIndexOutOfBoundsException("索引超出队列长度");
        }
    }

    //移除指定位置元素
    @Override
    public boolean remove(int i) {
        if (i < this.count) {
            for (int j = i; i < this.count - 1; j++) {
                this.arrayList[j] = this.arrayList[j + 1];
            }
            this.count--;
            return true;
        } else {
            throw new ArrayIndexOutOfBoundsException("索引超出队列长度");
        }
    }

    //队尾压入数组
    @Override
    public boolean push(E o) {
        this.arrayList[this.count++] = o;
        this.expandArray();
        return true;
    }

    //队首压入数组
    @Override
    public boolean unshift(E o) {
        for(int i = this.count; i > 0; i--) {
            this.arrayList[i] = this.arrayList[i - 1];
        }
        this.count++;
        this.arrayList[0] = o;
        this.expandArray();
        return true;
    }

    //队尾出数组
    @Override
    public E pop() {
        if (this.count > 0) {
            return (E)this.arrayList[this.count--];
        } else {
            return null;
        }
    }

    //队首出数组
    @Override
    public E shift() {
        if (this.count > 0) {
            Object tmp = this.arrayList[0];
            for (int i = 0; i < this.count; i++) {
                this.arrayList[0] = this.arrayList[i + 1];
            }
            this.count--;
            return (E)tmp;
        } else {
            return null;
        }
    }

    //数组容量扩充为原来的2倍,并将现有数组迁移入新的数组中
    private void expand() {
        this.Len *= 2;
        Object [] array = new Object[this.Len];
        for (int i = 0; i < count; i++) {
            array[i] = this.arrayList[i];
        }
        this.arrayList = array;
    }
    //判断数组是否已满,若数组已满,则扩充数组
    private void expandArray() {
        if (this.count == this.Len) {
            this.expand();
        }
    }

    //返回迭代器
    @Override
    @NotNull
    public Iterator<E> iterator() {
        return new ArrayLinearList.Itr();
    }

    //迭代器私有类
    private class Itr implements Iterator<E> {
        int cursor = 0;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such

        public boolean hasNext() {
            return cursor != count;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            int i = cursor;
            if (i >= count)
                throw new NoSuchElementException();
            cursor = i + 1;
            return (E) arrayList[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            try {
                ArrayLinearList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }
}

利用数组实现队列,数组的初始长度为8,当数组已满,则新建数组,新数组容量为现有数字的2倍,并将现有数组元素迁移至新数组。
同时,为队列实现了跌代器,利用跌代器可遍历容器。
具体实现并不难,大家可根据代码,理解一下,有利于理解java容器知识,如有疑问,请给我留言。

猜你喜欢

转载自blog.csdn.net/u011350550/article/details/83210795