您的位置:首页 > 理论基础 > 数据结构算法

顺序栈,共享栈以及链栈的相关操作

2017-07-31 20:47 591 查看
栈,后进先出的数据结构,可分为顺序栈,共享栈以及链栈。首先我们先说一下顺序栈。

顺序栈



顺序栈其实是在数组的基础上实现的,其数据结构定义了一个用来存储元素的数组和一个指向栈顶的指针。

class SeqStack{
Object[] data;;
int top;
}


定义好数据结构以后,首先先看一下顺序栈的初始化。

public static SeqStack initEmptyStack(){
SeqStack seqStack=new SeqStack();
seqStack.data=new Object[MAX_SIZE];
seqStack.top=-1;
return seqStack;
}


空栈的初始化根很简单,只需要将栈顶指针设为-1即可。接下来看判断栈是否为空的函数

public static boolean isEmpty(SeqStack seqStack){
if(seqStack.top==-1)
return true;
return false;
}


由于默认使用栈顶指针等于-1表示空栈,所以在判空时只需判断栈顶指针是否为-1

接下来是进栈函数。其思想是:如果没有超出栈的大小,则进栈,并将栈顶指针加1,否则进栈失败

public static boolean push(SeqStack seqStack,Object value){
if(seqStack.top+1==MAX_SIZE){
return false;
}
seqStack.data[++seqStack.top]=value;
return true;

}


最后是出栈,出栈的思想也很简单,如果栈为空,返回null,否则返回栈顶元素的值,并将栈顶指针的值减一

public static Object pop(SeqStack seqStack){
if(isEmpty(seqStack)){
return null;
}
int top=seqStack.top;
seqStack.top--;
return seqStack.data[top];
}


共享栈



共享栈是在顺序栈的基础上完成的,它利用栈底的位置不变,栈顶位置动态变化的特性,两个栈底分别是-1和MAX_SIZE-1,而他们的栈顶位置都会向中间方向延伸。按照此思想,我们给出共享栈的数据结构

class DupSeqStack {
Object[] data;
int leftTop;
int rightTop;
}


建立好数据结构,先对共享栈进行初始化。

public static  DupSeqStack initEmptyDumpSeqStack(){
DupSeqStack dupSeqStack=new DupSeqStack();
dupSeqStack.data=new Object[MAX_SIZE];
dupSeqStack.leftTop=-1;
dupSeqStack.rightTop=MAX_SIZE;
return  dupSeqStack;
}


由于将栈底位置分别设为-1和MAX_SIZE,所以在初始化空栈时只需要将leftTop设为-1,rightTop设为MAX_SIZE。接着就是比较常用的函数进栈和出栈。它的思想和顺序栈的思想是一样的,只不过我们在它的基础上加了一个标志flag来判断左进栈还是右进栈(或者是左出栈,右出栈)。当flag为真时,代表左进栈或者是左出栈;当flag为假时,代表右进栈或者右出栈。具体代码如下

//入栈
public static boolean push(DupSeqStack dupSeqStack,boolean flag,Object value){
if(dupSeqStack.leftTop+1==dupSeqStack.rightTop){
return false;
}
if(flag){
dupSeqStack.data[++dupSeqStack.leftTop]=value;
}else{
dupSeqStack.data[--dupSeqStack.rightTop]=value;
}
return true;
}
//出栈
public static Object pop(DupSeqStack dupSeqStack,boolean flag){
if(flag){
if(dupSeqStack.leftTop==-1){
return null;
}else{

return dupSeqStack.data[dupSeqStack.leftTop--];
}
}else{
if(dupSeqStack.rightTop==MAX_SIZE){
return null;
}else{
return dupSeqStack.data[dupSeqStack.rightTop++];
}
}
}


链栈



所谓链栈就是用链表的形式将元素组合起来,并让其符合栈后进先出的特性。为了达到这一目的,我们可以利用链表头插法的特性实现。先看一下它的数据结构

class LinkStack{
Object value;
LinkStack next;
}


链栈的数据结构其实和链表的一样。

public static boolean push(LinkStack top,Object value){
LinkStack node=new LinkStack();
node.value=value;
node.next=top.next;
top.next=node;
return true;
}


上述代码采用头插法进行入栈,具体思想可以参考单链表的创建

最后就是出栈方法。我们得判断栈顶指针是否为空,不为空则出栈,并返回其值。

public static Object pop(LinkStack top){
if(top.next!=null){
LinkStack node=top.next;
top.next=node.next;
return node.value;
}
return null;
}


总结

共享栈和顺序栈都是基于数组实现的,所以在此我们先将其归为一类,统称为顺序栈。接下来我们就说一下链栈和顺序栈的区别:顺序栈需要分配固定的空间,无法避免因数组空间用光导致溢出的问题,也无法避免空间浪费的问题,而链栈则是动态分配空间,通常是不会出现栈满的情况,正是因为在使用的时候动态分配,所以也不会出现空间浪费的情况
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构