1.数组实现队列
1.定义队列的接口
public interface MyQueue {
int size(); //获取队列的容量大小
boolean isEmpty(); //判断队列是否为空
void offer(Integer value); //将元素从队列尾部加入
int poll(); //将元素从队列头部删除
int peek(); //获取队列头部元素
}
2.设计接口的实现类
首先准备一个数组,一个头指针和一个尾指针,我们用尾指针作为游标来控制入队的元素,用头指针来控制出队的元素,当两个指针在同一个位置时,就表示队列为空,另外对列头部元素,我们用first指针下一个位置元素来表示,队列的容量用两个指针间的距离来表示。
对于offer方法,当队列满了,就抛异常,如果没满,我们就将last后移,并赋值为待入队元素。
对于poll方法,当队列为空时,直接抛异常,如果不为空,我们先记录队头元素,然后将原来队列头部置为0,最后返回记录到的元素。
public class ArrayQueue implements MyQueue{
private int N=10;
private int[] arr=new int[N];
private int first=-1;
private int last=-1;
ArrayQueue(){}
ArrayQueue(int capacity){
this.N=capacity;
}
@Override
public int size() {
return last-first;
}
@Override
public boolean isEmpty() {
return first==last;
}
@Override
public void offer(Integer value) {
if(size()==N){
throw new ArrayIndexOutOfBoundsException("队列已经满了,不能再加数据!");
}
arr[++last]=value;
}
@Override
public int poll() {
if(isEmpty()){
throw new ArrayIndexOutOfBoundsException("队列已经空了,没有数据!");
}
int value=arr[first+1];
arr[++first]=0;
return value;
}
@Override
public int peek() {
if(isEmpty()){
throw new ArrayIndexOutOfBoundsException("队列已经空了,没有数据!");
}
return arr[first+1];
}
}
3.验证设计的正确性
public class Main {
public static void main(String[] args){
ArrayQueue queue=new ArrayQueue();
queue.offer(1);
queue.offer(2);
queue.offer(4);
queue.offer(3);
queue.offer(5);
System.out.println(queue.isEmpty());
System.out.println(queue.peek());
queue.poll();
System.out.println(queue.poll());
System.out.println(queue.peek());
}
}
最终打印的结果:
2.数组实现栈
1.定义栈的接口
public interface MyStack {
int size(); //获取栈的容量大小
boolean isEmpty(); //判断栈是否为空
void push(Integer value); //将元素从栈顶压入
int pop(); //将元素从栈顶弹出
int peek(); //获取栈顶元素
}
2.设计接口的实现类
既然是数组实现,我们首先准备一个大小为10的数组(参考ArrayList的源码),然后准备一个记录栈容量大小的变量N,由于入栈和压栈只在栈顶进行,所以我们只需关注栈顶的下标和对应元素。
对于push的实现,当压入一个元素时,可能容量会超出初始设定的数值,所以先判断是否需要扩容,如果不需要,跳过扩容操作,直接设置N下标对应元素为入栈的元素,并跟新容量大小;如果需要扩容,先新建一个容量大小为原来2倍的临时数组,然后把原数组值全部复制到临时数组,最后再将原数组替换为临时数组,完成扩容。(如果不考虑扩容,直接抛异常)
对于pop的实现,首先进行判空操作,如果为空,则直接返回-1;然后记录弹出元素,并将弹出位置值重设为0(就想象是正常push的逆操作)。
public class ArrayStack implements MyStack{
private int[] arr=new int[10];
private int N=0;
@Override
public int size() {
return N;
}
@Override
public boolean isEmpty() {
return N==0;
}
@Override
public void push(Integer value) {
check();
arr[N]=value;
N++;
}
@Override
public int pop() {
if(isEmpty()){
return -1;
}
int value=arr[--N];
arr[N]=0;
return value;
}
@Override
public int peek() {
if(isEmpty()){
return -1;
}
return arr[N-1];
}
/**
* 判断是否超过原始设置容量,如果超过,则扩容为原来的2倍
*/
private void check(){
if(N>=arr.length){
resize(2*arr.length);
}
}
/**
* 扩容
* @param size 扩容后的容量大小
*/
private void resize(int size){
int[] temp=new int[size];
for(int i=0;i<N;i++){
temp[i]=arr[i];
}
arr=temp;
}
}
3.验证设计的正确性
public class Main {
public static void main(String[] args){
ArrayStack stack=new ArrayStack();
stack.push(1);
stack.push(3);
stack.push(2);
stack.push(5);
stack.push(4);
System.out.println(stack.isEmpty());
System.out.println(stack.peek());
System.out.println(stack.size()+"----");
stack.pop();
System.out.println(stack.size()+"----");
System.out.println(stack.pop());
System.out.println(stack.size()+"----");
System.out.println(stack.peek());
}
}
最终打印的结果: