栈与队列的异同
二者的相同点:
1.他们都属于线性表。
2.线性表的特点是数据元素之间存在“一对一”的关系,栈和队列都是操作受限制的线性表。
3.都只能在线性表的端点插入和删除
不同之处:
栈(Stack)是只允许在表的尾端进行插入或删除,(在栈中就是“栈顶”),其最大的特点是“先进后出或后进的先出”,可以类比为弹夹中压子弹,最后压的子弹却是最先射出的。
队列(Queue)是只允许在表尾进行插入数据,表头进行删除操作的线性表,其最大的特点是“先进先出”,就和我们在食堂打饭时排队一样,先打完的人先离开。
下面我用数组分别实现了栈与队列。
package demoo2;
import java.util.Arrays;
/**
*
* 实现栈
* 类比压子弹,先放后出
* 实现的方法有:压入元素,取出栈顶元素,查看栈顶元素,判断栈是否为空
* 注意有返回值的方法,只能通过打印此方法的看到返回值
*/
public class MyStack {
// 栈的底层我们使用数组来存取
private int[] elements;
// 构造方法初始化
public MyStack() {
elements = new int[0];
}
// 压入元素,放在末尾
public void push(int element) {
// 先建一个新的数组,把元素转移
int[] newArr = new int[elements.length + 1];
for (int i = 0; i < elements.length; i++) {
newArr[i] = elements[i];
}
newArr[newArr.length - 1] = element;
// 替换旧的数组
elements = newArr;
}
// 取出栈顶元素的方法
public int pop() {
// 如果栈内无元素,抛出异常
if (elements.length == 0) {
throw new RuntimeException("栈内为空");
}
//取出栈顶元素(也就是最后一个元素)
int element =elements[elements.length-1];
// 新建一个数组,转移元素
int[] newArr = new int[elements.length - 1];
for (int i = 0; i < newArr.length; i++) {
newArr[i] = elements[i + 1];
}
// 替换原数组
elements = newArr;
// 弹出栈顶元素
return element;
}
// 显示栈内元素的方法
public void show() {
System.out.println(Arrays.toString(elements));
}
// 查看栈顶元素
public int peek() {
return elements[0];
}
//判断栈是否为空
public boolean isEmpty(){
return elements.length==0;
}
}
栈的测试方法
package demo2_text;
import demoo2.MyStack;
public class StackText {
public static void main(String[] args) {
MyStack ms =new MyStack();
//压入元素
ms.push(9);
ms.push(8);
ms.push(7);
ms.push(6);
ms.push(5);
ms.show();
//删除栈顶元素
ms.pop();
ms.pop();
ms.pop();
ms.pop();
ms.show();
System.out.println(ms.peek()); //注意有返回值的方法,只能通过打印此方法的返回值看到具体执行结果
ms.pop();
System.out.println(ms.isEmpty());
}
}
/**
* 2019年2月1日
*/
package demoo2;
import java.util.Arrays;
/**
* 队列的实现
*
*/
public class MyQueue {
private int[] elements;
// 初始化队列
public MyQueue() {
elements = new int[0];
}
// 入队的方式
public int add(int element) {
// 创建一个新数组
int newArr[] = new int[elements.length + 1];
// 把原来的数据放在新数组里面
for (int i = 0; i < elements.length; i++) {
newArr[i] = elements[i];
}
// 把要添加的数据放在队尾
newArr[elements.length] = element;
// 将新数组代替旧数组
elements = newArr;
return element;
}
// 出队的方法
public int poll() {
// 把数组的第0个元素取出来,因为是从队头删去
int element = elements[0];
// 创建一个新数组
int newArr[] = new int[elements.length -1];
// 把原来的数据放在新数组里面
for (int i = 0; i < newArr.length; i++) {
newArr[i] = elements[i+1];
}
// 将新数组代替旧数组
elements = newArr;
return element;
}
//判断队列是否为空
public boolean isEmpty(){
return elements.length==0;
}
//显示队列元素的方法
public void show(){
System.out.println(Arrays.toString(elements));
}
}
队列的测试方法
package demo2_text;
import demoo2.MyQueue;
public class QueueText {
public static void main(String[] args) {
//创建一个队
MyQueue mq =new MyQueue();
//入队
mq.add(10);
mq.add(20);
mq.add(30);
mq.add(40);
mq.add(50);
mq.add(60);
mq.show();
//出队
mq.poll();
mq.poll();
mq.show();
//判断队列是否为空
System.out.println(mq.isEmpty());
}
}
注意以下几点:
1.有些方法内部没有打印,而是通过加返回值的方式,好处是可以不断地 调用,坏处是如果要知道结果必须得在主方法中调用打印
2.在删除元素时必须要判断数组内部是否为空,如果为空就要抛出异常,
throw new RuntimeException("栈内为空");