概述
写在前面的话:
1.熟悉栈、队列相关知识
2.熟悉数组的中间插入
3.熟悉数组如何扩容
目录
1.双端队列
2.测试双端队列
项目结构:(双端队列同样属于栈&队列范畴)
1.双端队列
Deque.java
/*
双端队列:[拓展知识]
简单的介绍:
1.为了充分利用数组空间,特此采用循环队列
2.本程序考察了参数的应用、数组的中间插入和超范围插入(扩容)
3.存储方式可以用数组外,还可以采用链表(本程序当中未涉及)
技巧:
1.熟悉栈与队列,之后无障碍阅读
2.熟悉数组的中间插入
3.熟悉数组如何进行扩容
*/
public class Deque {
private int[] array;
private int font;//双端队列也是队列!同样有队头
private int rear;
int size;//元素个数
public Deque(){
array = new int[10];
}
//指定长度的队列
public Deque(int capacity){
array = new int[capacity];
}
/**
* 入队
* @param element 插入的元素
* @param front_or_behind 从后面插入元素(参数填入:behind)还是前面插入元素(参数填入:front)
*/
public void enDeque(int element,String front_or_behind){
//不管是在前面插入或者后面插入,当队列为空时,插入元素只有1种可能
if(size == 0){
array[0] = element;
rear += (rear + 1)%array.length;
size++;
return;//插入完毕,直接返回
}
//判断插入顺序
if(front_or_behind == "front"){
//判断队列是否已满
if(size >= array.length - 1){//元素个数大于或等于数组长度(要留一个,故减一)
//进行扩容
expandCapacity();
}
//队列未满可进行插入
insert(font,element);//在队头插入数据
}else if(front_or_behind == "behind"){
//判断队列是否已满
if(size >= array.length - 1){//元素个数大于或等于数组长度(要留一个空,故减一)
//进行扩容
expandCapacity();
}
//队列未满可进行插入
array[rear] = element;
rear = (rear + 1)%array.length;
size++;//元素个数加1
}else{
//输入有误
throw new IllegalArgumentException("输入参数有误!非front或behind!");
}
}
/**
* 出队
* @param front_or_behind 从后面删除元素(参数填入:behind)还是前面删除元素(参数填入:front
*/
public void outDeque(String front_or_behind) throws Exception{
//判断队列是否为空
if(size == 0){
throw new Exception("队列为空,无法获取数据");
}
if(front_or_behind == "front"){
font = (font + 1)%array.length;
size--;//元素个数减一
}else if(front_or_behind == "behind"){
rear--;
if(rear <= -1){
rear = array.length - 1;
}
size--;//元素个数减一
}else{
throw new IllegalArgumentException("输入参数有误!非front或behind!");
}
}
public void expandCapacity(){
int[] newArray = new int[array.length * 2];
if(newArray.length > 100){
throw new IllegalArgumentException("不准栈的深度超过100");
}
//将原数组复制到新数组里
for(int i = font,n = 0;n < size;i = (i + 1)%array.length){
newArray[n++] = array[i];
}
//扩大后,队头队尾发生变化
font = 0;
rear = size;
array = newArray;
}
/**
* 数组的中间插入、超范围插入(扩容)
* @param index 插入的位置
* @param element 插入的元素
*/
public void insert(int index , int element){
//在这里不需要判断是否需要扩容,在调用该方法前已经判断了
//判断index是否超出数组范围
if(index < 0 || index > array.length){//还不完善,有能力可以进一步修改
throw new IllegalArgumentException("参数index不符合范围!参数index的值:" + index);
}
//在数组下标index以及之后的元素依次往后移动(记住:这里是循环队列!如:array[array.length] == array[0])
//
// 在这里分两种情况:
// 1.rear后面没有接元素:这种比较简单,元素依次往后移一位【常规写法】
// 2.rear后面有元素(队尾在中间):这种比较麻烦,关键在于后面有个元素是队头
//
if(rear >= font){
//这种情况说明:常规情况,[1,font,...,2,3,4,rear]
for(int i = rear - 1;i >= index;i--){
array[i + 1] = array[i];//往后移
}
}else{
//这种情况说明:[1,2,rear,...,3,4,font,...]
for(int i = rear - 1;i != index;i--){
if(i <= -1){
i = array.length - 1;
array[0] = array[i];
continue;
}
array[i + 1] = array[i];
}
array[(index + 1)%array.length] = array[index];//将队头向后移
}
//将元素插入数组下标index处 ==> 数组更新操作
array[index] = element;
//插入后,元素个数增加,队尾加1
size++;
rear = (rear + 1)%array.length;
}
@Override
public String toString() {
String str = "[";
//只遍历数组当中的元素个数
// 分两种情况:
// 1. rear >= font [1,font,...,2,3,4,rear]
// 2. rear < font [1,2,rear,...,3,4,font,...]
if(rear >= font){
//常规解法,依次遍历即可
for(int i = font;i < rear;i = (i + 1)%array.length){
str += array[i];
//当不是最后1个元素,需要加逗号
if(i != rear - 1){
str += ",";
}
}
}else{
//rear < font情况
for(int i = font;i < size;i = (i + 1)%array.length){
str += array[i];
//当不是最后1个元素,需要加逗号
if(i != rear - 1){
str += ",";
}
}
}
//最后加一个"]"结尾
str += "]";
return str;
}
}
2.测试双端队列
TestArray.java
public class TestArray {
public static void main(String[] args) {
Deque deque = new Deque(3);
System.out.println("入队:");
deque.enDeque(1,"behind");
deque.enDeque(2,"behind");
deque.enDeque(3,"front");
deque.enDeque(4,"front");
deque.enDeque(5,"behind");
deque.enDeque(6,"behind");
deque.enDeque(7,"front");
System.out.println(deque);
System.out.println("出队:");
try {
deque.outDeque("front");
deque.outDeque("behind");
deque.outDeque("front");
deque.outDeque("front");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(deque);
System.out.println("入队:");
deque.enDeque(-1,"front");
deque.enDeque(6,"behind");
deque.enDeque(-4,"front");
deque.enDeque(-5,"behind");
System.out.println(deque);
System.out.println("出队:");
try {
deque.outDeque("front");
deque.outDeque("behind");
deque.outDeque("front");
deque.outDeque("front");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(deque);
}
}
完
最后
以上就是美满发卡为你收集整理的双端队列数组版【Java算法(五)】1.双端队列 2.测试双端队列的全部内容,希望文章能够帮你解决双端队列数组版【Java算法(五)】1.双端队列 2.测试双端队列所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复