1.什么是栈
后进先出(LIFO)的线性表,仅能在一边进出。
2.实现方式有:顺序栈和链式栈
顺序栈的实现:将数组的尾部当作栈顶,在栈顶尾部进行pop和push操作只需要常数时间。
//顺序栈的实现
public class Astack implements StackADT{
private static final int defaultsize=10;//栈的默认大小
private int size;//栈的最大大小
private int top;//栈顶指针,其实这里指向的是栈的第一个空位
private Object[] listArray;//用于承载栈元素的数组
Astack(int size){
init(size);
}
Astack(){
init(defaultsize);
}
void init(int size){
this.size=size;
listArray=new Object[size];
top=0;
}
@Override
public void clear() {
// TODO Auto-generated method stub
top=0;
}
@Override
public void push(Object item) {
// TODO Auto-generated method stub
if(top>=size){
System.out.println("stack overflow");
}
else {
listArray[top++]=item;
}
}
@Override
public Object pop() {
// TODO Auto-generated method stub
if(isEmpty()){
System.out.println("stack is empty");
}
else{
return listArray[--top];
}
return null;
}
@Override
public Object topValue() {
// TODO Auto-generated method stub
if(isEmpty()){
System.out.println("stack is empty");
}
else{
return listArray[top-1];
}
return null;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return top==0;
}
}
相对增长栈:
当两个栈有着此消彼长型关系时,可将两个栈用同一个数组实现,相对生长,节省空间。
链式栈的实现方式:
//链式栈的实现
public class Lstack implements StackADT{
private Link top;
Lstack(int size){
init();
}
Lstack(){
init();
}
void init(){
top=null;
}
@Override
public void clear() {
// TODO Auto-generated method stub
top=null;
}
@Override
public void push(Object item) {
// TODO Auto-generated method stub
top=new Link(item,top);
}
@Override
public Object pop() {
// TODO Auto-generated method stub
if(isEmpty()){
System.out.println("stack is empty");
}
else{
Object item=top.element();
top=top.next();
return item;
}
return null;
}
@Override
public Object topValue() {
// TODO Auto-generated method stub
if(isEmpty()){
System.out.println("stack is empty");
}
else{
return top.element();
}
return null;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return top==null;
}
}
用栈模拟递归(递归并不能总可用被迭代代替)
例如,汉诺塔的递归程序
//汉诺塔的递归实现
void TOH(int n,int start,int goal,int temp){
if(n==0)return;
TOH(n-1,start,temp,goal);//将n-1块从start柱子移动到temp柱
move(n,start,goal);//将第n块移动到目标柱
TOH(n-1,temp,goal,start);//将n-1块从temp柱子移动到目的柱
}
用栈模拟:
//栈模拟的汉诺塔实现
void TOHinStack(int n,int start,int goal,int temp){
Astack as=new Astack(1000);
as.push(new TOHobj(TOH,n,start,goal,temp));
while(!as.isEmpty()){
TOHobj it=(TOHobj)as.pop();
if(it.op==MOVE){
move(it.num,it.start,it.goal);
}
else if(it.num>0){
as.push(new TOHobj(TOH,it.num-1,it.temp,it.goal,it.start));
as.push(new TOHobj(MOVE,it.num,it.start,it.goal));
as.push(new TOHobj(TOH,it.num-1,it.start,it.temp,it.goal));
}
}
}
注意的是操作入栈的顺序和原本调用的顺序是相反的,因为栈是先进后出的线性表。