数据结构:用Java实现双端队列(超详细)

Java双端队列

典型的双端队列收集如下所示:

Java中的双端队列收集

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

 

left:左端    right:右端

这里我们使用最常用的顺序结构来存储双端队列,为了节省空间,把它首尾相连,构成循环队列。并且规定left指向左端的第一个元素,right指向右端的下一个位置。那么队空的判断则是left==right,队满是(left-1+MAX)%MAX==right或者(right-left+MAX)%MAX==MAX。
 

创建实现双端队列方法类:

class ListNode {
    //数据域
    public int val;
    //指针
    public ListNode next;
    //初始化值
    public ListNode(int val) {
        this.val = val;
    }
}

public class Deque {
    public ListNode head;//头结点
    public ListNode last;//尾节点

    //在双端队列头那边添加节点变成新的头结点
    //在第一个节点处添加一个节点
    public void addFirst(int val) {
        //创建对象初始化值建立新节点
        ListNode node = new ListNode(val);
        //判断尾节点是否为空
        if (this.last == null) {
            //若为空就是头结点尾节点都是这个新创建的节点
            this.head = node;
            this.last = node;
        }
        //node成为新的头节点
        node.next = this.head;
        this.head = node;
    }

    //在双端队列尾那边添加节点变成新的尾节点
    //在节点的最后添加一个节点
    public void addLast(int val) {
        //创建对象初始化值建立新节点
        ListNode node = new ListNode(val);
        //判断尾节点是否为空
        if (this.last == null) {
            //若为空就是头结点尾节点都是这个新创建的节点
            this.head = node;
            this.last = node;
        }
        //node成为新的尾节点
        this.last.next = node;
        this.last = node;
    }

    //从头结点那边拿出Deque的一个节点
    public int offerFirst() {
        //判断头节点是否为空,如果是就输出!
        if (this.head == null) {
            System.out.println("!");
            return -1;
        }
        //如果不为空,把头结点指向的值拿出来
        int oldValue = this.head.val;
        //判断头结点尾节点是否重合,如果重合就表明双端队列为空
        if (this.head == this.last) {
            this.head = null;
            this.last = null;
        } else {
            //没有重合就接着找下一个节点变成新的头结点
            this.head = this.head.next;
        }
        return oldValue;
    }

    //从尾结点那边拿出Deque的一个节点
    public int offerLast() {
        //判断尾节点是否为空,如果就输出!
        if (this.last == null) {
            System.out.println("!");
            return -1;
        }
        // //如果不为空,把尾结点指向的值拿出来
        int oldValue = this.last.val;
        //判断头结点尾节点是否重合,如果重合就表明双端队列为空
        if (this.head == this.last) {
            this.last = null;
            this.head = null;
        } else {
            //遍历找到新的尾节点
            ListNode cur = this.head;
            while (cur.next != last) {
                cur = cur.next;
            }
            //把找到的最后一个节点做为尾节点
            this.last = cur;
            //尾节点.next=null
            this.last.next = null;
        }
        return oldValue;
    }

    //获取Deque处第一个节点的值
    public int peekFirst() {
        //判断头结点是否为空,是就输出!
        if (this.head == null) {
            System.out.println("!");
            return -1;
        }
        //返回头结点值
        return this.head.val;
    }

    //获取Deque上最后一个节点的值
    public int peekLast() {
        //判断尾结点是否为空,是就输出!
        if (this.last == null) {
            System.out.println("!");
            return -1;
        }
        //返回尾结点值
        return this.last.val;
    }

    //Check whether the Deque is empty
    public boolean empty() {
        return this.head == null;
    }

    public void display(){
        ListNode cur =head;
        while (cur!=last) {
            System.out.println(cur.val);
            cur = cur.next;
        }
        System.out.println(cur.val);
    }
}

创建测试类:

public class DequeTest {
    public static void main(String[] args) {
        Deque deque=new Deque();
        deque.addFirst(1);
        deque.addFirst(2);
        deque.addFirst(3);
        deque.display();
        deque.offerFirst();
        System.out.println();
        deque.display();
    }
}

测试结果:

 

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
双端队列(Deque)是一种具有队列和栈的性质的数据结构,它允许从两端插入和删除元素。 Java中提供了Deque接口来实现双端队列,常用的实现类有LinkedList和ArrayDeque。下面是使用数组实现双端队列Java代码: ```java public class ArrayDeque<E> { private E[] data; private int front; private int rear; private int size; public ArrayDeque(int capacity) { data = (E[]) new Object[capacity]; front = rear = 0; size = 0; } public ArrayDeque() { this(10); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public void addFirst(E e) { if (size == data.length) { resize(2 * data.length); } front = (front - 1 + data.length) % data.length; data[front] = e; size++; } public void addLast(E e) { if (size == data.length) { resize(2 * data.length); } data[rear] = e; rear = (rear + 1) % data.length; size++; } public E removeFirst() { if (isEmpty()) { throw new IllegalArgumentException("Deque is empty."); } E ret = data[front]; data[front] = null; front = (front + 1) % data.length; size--; if (size == data.length / 4 && data.length / 2 != 0) { resize(data.length / 2); } return ret; } public E removeLast() { if (isEmpty()) { throw new IllegalArgumentException("Deque is empty."); } rear = (rear - 1 + data.length) % data.length; E ret = data[rear]; data[rear] = null; size--; if (size == data.length / 4 && data.length / 2 != 0) { resize(data.length / 2); } return ret; } public E getFirst() { if (isEmpty()) { throw new IllegalArgumentException("Deque is empty."); } return data[front]; } public E getLast() { if (isEmpty()) { throw new IllegalArgumentException("Deque is empty."); } return data[(rear - 1 + data.length) % data.length]; } private void resize(int newCapacity) { E[] newData = (E[]) new Object[newCapacity]; for (int i = 0; i < size; i++) { newData[i] = data[(i + front) % data.length]; } data = newData; front = 0; rear = size; } @Override public String toString() { StringBuilder res = new StringBuilder(); res.append(String.format("Deque: size = %d, capacity = %d\n", size, data.length)); res.append("front ["); for (int i = front; i != rear; i = (i + 1) % data.length) { res.append(data[i]); if ((i + 1) % data.length != rear) { res.append(", "); } } res.append("] rear"); return res.toString(); } } ``` 其中,data数组表示队列的容器,front和rear表示队列的头和尾,size表示队列的大小。addFirst方法在队头添加元素,addLast方法在队尾添加元素,removeFirst方法从队头删除元素,removeLast方法从队尾删除元素,getFirst方法获取队头元素,getLast方法获取队尾元素。resize方法用于动态调整数组容量。toString方法用于打印队列的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值