目录
前言
栈和队列的区别不仅仅是栈是先进后出,而队列是先进先出
在代码设计思路和代码规范上也有很多值得注意的地方
笔者私以为,队列比栈有更多细节点需要注意
下面我将用数组对这两种数据结构进行分析
一、栈
1、栈的一个最重要的特征就是栈的插入和删除只能在栈顶进行,即表尾删除
2、代码实现栈的增删改查:
class ArrayStack{
private int maxsize;
private int stack[];
private int top=-1;//指向栈顶元素
public ArrayStack(int maxsize) {
this.maxsize = maxsize;
stack=new int[maxsize];
}
//判断栈是否为满
public boolean isFull(){
return top==maxsize-1;
}
//判断栈是否为空
public boolean isEmpty(){
return top==-1;
}
//向栈中添加数据
public void add(int n){
if(isFull()){
System.out.println("栈满,无法添加");
return;
}
top++;
stack[top]=n;
System.out.println("入栈成功");
}
//取出栈顶元素
public int get(){
if(isEmpty()){
throw new RuntimeException("栈中元素为空,无法取出");
}
int value=stack[top];
top--;
System.out.println("出栈成功");
return value;
}
//显示栈中元素
public void show(){
if(isEmpty()){
System.out.println("栈中无数据");
return;
}
System.out.println("栈中元素为:");
int key=top;
while(key!=-1){
System.out.printf("stack[%d]=%d\n",key,stack[key]);
key--;
}
}
//修改栈中元素
/**
* 将栈中下标为k的元素修改为value
* @param k 下标
* @param value 修改后的值
*/
public void update(int k,int value){
if(isEmpty()){
System.out.println("栈为空,无法修改");
return;
}
if(k<0||k>maxsize-1){
System.out.println("输入数据有误,请重新输入");
return;
}
stack[k]=value;
System.out.println("修改成功");
}
}
二、队列
1、队列一个最重要特点是插入在表尾进行,删除在表头进行,先进先出
2、代码实现队列的增删改查(要用到环形数组):
* 思路:取余运算达成循环 * 在数组容量后多加一个预留位置
public class CircleQueue {
private int maxsize;//数组最大容量
private int front;//队列头
private int rear;//队列尾
private int[] arr;//该数据用于存放数据,模拟队列
public CircleQueue(int arrMaxsize) {
maxsize = arrMaxsize;
arr = new int[maxsize];
front = 0;//指向队列头部,分析出front是指向队列头的第一个位置
rear = 0;//指向队列尾的数据的后一个位置!
}
public boolean isFull() {
return (rear + 1) % maxsize == front;
}
//判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
//添加数据到队列
public void addQueue(int n) {
//判断队列是否为满
if (isFull()) {
System.out.println("队列满,不能添加数据!");
return;
}
arr[rear] = n;
rear = (rear + 1) % maxsize;
}
//获取队列的数据,出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空,无法获取数据!");
}
int value = arr[front];
front = (front + 1) % maxsize;
return value;
}
//显示队列中所有元素
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,无数据!");
} else {
for (int i = front; i < front+size(); i++) {
System.out.printf("arr[%d]=%d\n", i%maxsize, arr[i%maxsize]);
}
}
}
//求出当前队列有效数据的个数
public int size()
{
return (rear+maxsize-front)%maxsize;
}
//显示队列的头数据,注意不是取出数据
public int headQueue() {
//判断是否为空
if (isEmpty()) {
throw new RuntimeException("队列为空,无数据!");
}
return arr[front];
}
/**
*
* @param k k表示下标为k的队列元素
* @param value 修改的值
*/
public void update(int k,int value){
if(isEmpty()){
System.out.println("队列为空,无法修改");
return;
}
if(k<0||k>maxsize-1){
System.out.println("输入数据有误,请重新输入");
return;
}
arr[k]=value;
System.out.println("修改成功");
}
}
3、注意事项:
1)front指向队列头部,rear指向队列尾的后一个位置,二者初始值都为0
2)队列采用环形数组,需要空一个元素的位置,所以最大存放maxsize-1个元素
为什么要空一个元素位置?
循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。
故约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空);