详细理解双端队列的实现及原理

双端队列的实现原理及概念

在这里插入图片描述
每日笑话:你好;uc浏览器更新以后,不仅是笑话没有了, 其它好用点的功能都没有了, 没有小说书架,不能缓存正本小说等, uc浏览器更新以后,变得很垃圾, 跟换了个浏览器似的,现在很多网友因此不在使用uc浏览器了,谢谢望采纳。

双端队列的定义

定义: 双端队列是限定插入和删除操作在表的两端进行的线性表。这两端分别称做端点1和端点2。也可像栈一样,可以用一个铁道转轨网络来比喻双端队列。在实际使用中,还可以有输出受限的双端队列(即一个端点允许插入和删除,另一个端点只允许插入的双端队列)和输入受限的双端队列(即一个端点允许插入和删除,另一个端点只允许删除的双端队列)。而如果限定双端队列从某个端点插入的元素只能从该端点删除,则该双端队列就蜕变为两个栈底相邻的栈了。双端队列(double ended queue,deque)是限定插入和删除操作在表两端进行的线性表,是具有队列和栈性质的数据结构。双端对列与普通队列的区别在于,双端队列可以在队列的头添加元素,队尾删除元素。

双端队列的实现

双端队列和循环队列的创建过程类似,都需要两个类似指针的标签,分别指向对首和队尾的下一个,因为要留一个null空间出来,方便判断队列满的条件。如下图:
在这里插入图片描述
初始状态front、rear都是指向双端队列的头部,图中的显示并不是表示循环对列从中间开始增加元素,并往两头走的情况。所以这一点还是值得注意!

示意图

1.初始状态
在这里插入图片描述
2.增添元素
(1)addLast();队尾添加元素
在这里插入图片描述
(2.addFirst());队头添加元素
在这里插入图片描述
3.删除元素

在这里插入图片描述
(1)removeLast();
在这里插入图片描述
在这里插入图片描述
(2)removeFirst();移除列首元素

在这里插入图片描述
在这里插入图片描述

实现代码

Deque接口

package 数据结构线性结构;

public interface Deque<E> extends Iterable<E> {//双端对列的接口
	public void addFirst(E element);//在列首添加元素
	public void addLast(E element);//在列尾添加元素
	public E removeFirst();//在列首删除元素
	public E removeLast();//在列尾部删除元素
	public E getFirst();//获取列首元素
	public E getLast();//获取列尾元素
	public int size();//获取有效长度
	public boolean isEmpty();//判段是否为空

}

ArrayDeque类------双端队列实现类

package 数据结构线性结构;

import java.util.Iterator;

public class ArrayDeque<E> implements Deque<E> {
	private E[] data;
	private int size;
	private int front;
	private int rear;
	private static int DEFAULIT_CAPACITY = 10;
			
	public ArrayDeque() {
	size = 0;
	rear = 0;
	front = 0;
	data = (E[])new Object[DEFAULIT_CAPACITY+1];
	}
	@Override
	public Iterator<E> iterator() {
		// TODO 自动生成的方法存根
		return null;
	}
	private class ArrayDequeiterator<E> implements Iterator<E>{
		 
	    private int cur =front;

		@Override
		public boolean hasNext() {
			// TODO 自动生成的方法存根
			return cur!=rear;
		}

		@Override
		public E next() {
			// TODO 自动生成的方法存根
			E ret = (E) data[cur];
			cur = (cur+1)%data.length;
			return ret;
		}
	    
	
		
	}

	@Override
	public void addFirst(E element) {//往列头添加元素
		// TODO 自动生成的方法存根
		if((rear+1)%data.length==front) {//判断队列满的时候
			resize(2*data.length-1);//扩容的方法
		}
		front = (front-1+data.length)%data.length;//防止列表头指针溢出,所以进行取data.length余数
		data[front] = element;
		size++;
		
	}
	public void resize(int newlength) {//扩容
		E[] newData =(E[]) new Object[newlength];//定义一个新元素数组
		int i = 0;//计数
		while(front!=rear) {//当遍历到front==rear,循环列表遍历结束
			newData[i++] = this.data[front];
			front = (front+1)%data.length;
		}
		data = newData;
		front = 0;
		rear = i;
	}

	@Override
	public void addLast(E element) {
		// TODO 自动生成的方法存根
		if((rear+1)%data.length==front) {
			resize(2*data.length-1);
		}
		data[rear]=element;
		rear = (rear+1)%data.length;
		size++;
		
	}

	@Override
	public E removeFirst() {
		// TODO 自动生成的方法存根
		E ret = data[front];//取元素
		if(size<(data.length-1)/4&&data.length-1>DEFAULIT_CAPACITY) {//缩容
			resize(data.length/2+1);
		}
		front = (front+1)%data.length;
		size--;
		return ret;
	}

	@Override
	public E removeLast() {

		if(size<(data.length-1)/4&&data.length-1>DEFAULIT_CAPACITY) {
			resize(data.length/2+1);
		}
		rear = (rear-1+data.length)%data.length;		
		E ret = data[rear];
		size--;
		return ret;
	}

	@Override
	public E getFirst() {
		// TODO 自动生成的方法存根
		return data[front];
	}

	@Override
	public E getLast() {
		// TODO 自动生成的方法存根
		return data[rear-1];
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append('{');
		int i =rear,j=front;
		while(rear!=front) {
			sb.append(data[front]);
			front = (front+1)%data.length;
			if(rear==front) {
				sb.append('}');
				break;
			}else {
				sb.append(',');
			}
		}
		rear = i;
		front = j;
		return sb.toString();
	}
	@Override
	public int size() {
		// TODO 自动生成的方法存根
		return size;
	}

	@Override
	public boolean isEmpty() {
		// TODO 自动生成的方法存根
		return size==0;
	}

}


ArrayDequeTest测试类:

package 数据结构线性结构;

public class DequeTest {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		ArrayDeque <Integer>que = new ArrayDeque<>();
		que.addFirst(new Integer(1));
		que.addFirst(new Integer(2));
		que.addFirst(new Integer(3));
		que.addFirst(new Integer(4));
		que.addLast(new Integer(5));
		que.addLast(new Integer(6));
		que.addLast(new Integer(7));
		que.addLast(new Integer(8));
		System.out.println(que);
		System.out.println(que.removeLast());
		System.out.println(que.removeFirst());
		System.out.println(que);
	}

}

结果
在这里插入图片描述

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛牛最爱喝兽奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值