什么是栈
仅在表尾进行插入和删除操作的线性表。其中,表尾叫栈顶,表头叫栈底。
满足后进先出(LIFO)原则。
基于栈的属性和操作
数组实现,数据元素假设为int类型
属性:
private int[] value;
private int stackSize;
操作:
public void initStack(int maxSize);
public void clearStack();
public boolean push(int newValue);
public int pop();
public boolean isEmpty();
public int getStackSize();
public int getTop();
JAVA实现
java语言中的jdk本身提供了java.util.Stack类,它继承了Vector类,底层利用Vector(动态数组)来实现栈的数据结构。
手动实现
1、Stack类
package com.stack.study;
public class Stack {
private int[] value;
private int stackSize;
public void initStack(int maxSize){
this.value = new int[maxSize];
this.stackSize=0;
}
public void clearStack(){
for(int i=0;i<this.stackSize;i++){
this.value[i]=0;
}
}
public boolean push(int newValue){
if(stackSize>=value.length){
return false;
}else{
this.value[this.stackSize++]=newValue;
return true;
}
}
public int pop(){
return this.value[--this.stackSize];
}
public boolean isEmpty(){
if(this.stackSize==0){
return true;
}else{
return false;
}
}
public int getStackSize(){
return this.stackSize;
}
public int[] getValue() {
return value;
}
public void setValue(int[] value) {
this.value = value;
}
public void setStackSize(int stackSize) {
this.stackSize = stackSize;
}
}
2、测试
package com.stack.study;
public class Test {
public static void main(String[] args){
Stack stack = new Stack();
stack.initStack(5);
System.out.println(stack.isEmpty());
System.out.println(stack.getStackSize());
stack.push(2);
stack.push(0);
stack.push(4);
System.out.println(stack.isEmpty());
System.out.println(stack.getStackSize());
stack.pop();
stack.pop();
System.out.println(stack.isEmpty());
System.out.println(stack.getStackSize());
}
}
3、测试结果
true
0
false
3
false
1
扩展
用数组(顺序表)实现的栈在栈满后如果还需要开辟空间,就要新建一个更大的数组,并把原来的数组copy到新数组中,效率比较低,这种情况比较多的时候用链表实现栈的效果更好。
栈的应用
数制转换、括号匹配检验、迷宫求解(穷举法)、表达式求值、递归等。
以后我会专门编程实现以上应用,并专门学习总结递归的原理。
什么是队列
只允许在表的一端插入元素(队尾),在表的另一端删除元素(对头)的线性表。
满足FIFO(先进先出)原则。
队列的形式
队列除了普通的先进先出队列外,还有双端队列(两端都可以插入和删除),链式队列(两个指针,指向队头和队尾),循环队列(下文讲解)。
java实现
java的java.util包中提供了queue接口,可以提供队列的一些操作。
手动实现
1、queue类
package com.queue.study;
public class Queue {
private int[] value;
private int queueSize;
private int queueTail; //队尾的下标
private int queueHead;
public void initQueue(int maxSize){
this.value = new int[maxSize];
this.queueSize = 0;
this.queueHead = 0;
this.queueTail = -1;
}
public int getQueueTail() {
return queueTail;
}
public void setQueueTail(int queueTail) {
this.queueTail = queueTail;
}
public int getQueueHead() {
return queueHead;
}
public void setQueueHead(int queueHead) {
this.queueHead = queueHead;
}
public void destroyQueue(){
this.value = null;
this.queueSize = 0;
this.queueHead = -1;
this.queueTail = -1;;
}
public void clearQueue(){
for(int i = 0;i<this.queueSize;i++){
this.value[i] = 0;
}
this.queueHead = -1;
this.queueTail = -1;
this.queueSize = 0;
}
public int getHead(){
return this.value[this.queueHead];
}
public boolean enQuque(int enValue){
if(this.queueTail == this.value.length-1){
return false;
}else{
this.value[++this.queueTail] = enValue;
this.queueSize++;
return true;
}
}
public boolean deQueue(){
if(this.queueSize == -1){
return false;
}else{
this.value[this.queueHead++] = 0;
this.queueSize--;
return true;
}
}
public int[] getValue() {
return value;
}
public void setValue(int[] value) {
this.value = value;
}
public int getQueueSize() {
return queueSize;
}
public void setQueueSize(int queueSize) {
this.queueSize = queueSize;
}
}
2、测试
package com.queue.study;
public class Test {
public static void main(String[] args){
Queue queue = new Queue();
queue.initQueue(5);
queue.enQuque(6);
queue.enQuque(0);
queue.enQuque(2);
System.out.println(queue.getHead());
queue.deQueue();
System.out.println(queue.getHead());
queue.deQueue();
System.out.println(queue.getHead());
}
}
3、测试结果
6
0
2
循环队列
队列如果不停的进队和出队,因为元素都是从队头出队,从队尾入队。队头和队尾的下标就会逐渐增大,这样就会导致出队后的元素的下标无法被继续利用,浪费存储空间,为了解决这个问题,我们引入循环队列。
顾名思义,循环队列在形式上就是一个圆环,比如线性表有5个元素。则下标为4的元素的下一个元素的下标又回到0。
实现略。。。