数据结构学习笔记(3):栈

  • 前言

栈的逻辑结构其实也是线性表,只不过它的插入和删除操作受限,如下图所示:

       栈只有一端能够插入和删除,这端叫做栈顶;而不同操作的一端就称为栈顶。所以,后面进入栈的元素能够被优先删除,这种特性被称为后进先出(Last In First Out,LIFO)。

  • 顺序栈

顺序栈,顾名思义,就是用顺序存储实现的栈,它使用一连串连续的存储单元来存储栈元素,同时加入一个指针,表明现在栈的元素个数。

2.1顺序栈的定义

       顺序栈的定义如下所示:

#define MaxSize 50

typedef struct

{

Elemtype data[MaxSize];

int top;

}SqStack;

       包含一个存储元素的数组和一个栈顶指针。值得注意的是,一般top为数组的下标,所以top最大取值为MaxSize-1。

2.2顺序栈的初始化

       顺序栈的初始化只需要把栈顶指针设置为-1即可,表示空表:

void InitStack(SqStack &S)

{

S.top=-1;

}

2.3判断顺序栈是否为空

       当顺序栈的栈顶指针为-1时,自然为空:

bool StackEmpty(SqStack S)

{

if(S.top==-1)

return true;

else

return false;

}

2.4进栈

       当要输入新的元素进栈时,代码如下:

bool Push(SqStack &S, Elemtype x)

{

if(S.top==MaxSize-1)

return false;

S.data[++S.top]=x;

return true;

}

       值得注意的是,数组下标内++S.top的意思是,先给top指针加一,表示栈内元素加一,然后再以加一后的下标作为插入的位置,然后在此位置插入元素x。

2.5出栈

       当要删除栈顶元素时,代码如下:

bool Pop(SqStack &L,Elemtype &x)

{

if(S.top==-1)

return false;

x=S.data[S.top--];

return true;

}

       同样的,S.top--的意思是先读取S.top后再对其减一。

2.6读取栈顶元素

       即读取top位置的元素:

bool GetTop(SqStack &S,Elemtype &x)

{

if(S.top==-1)

return false;

x=S.data[S.top];

return true;

}
  • 链栈

链栈就是用链式存储实现的栈,如果是链式存储,那么容量理论上是可以比顺序存储大很多。

3.1链栈的定义

       链栈和链表一样,一个节点包括一个数据域和一个指针域,这里以带头节点的链栈作例,代码如下:

typedef struct LinkedStackNode

{

Elemtype data;

LinkedStackNode* next;

}LinkedStackNode,*LinkedStack;

3.2链栈的初始化

LinkedStack InitStack(LinkedStack &S)

{

S=(LinkedStackNode*)malloc(sizeof(LinkedStackNode));

S.next=NULL;

retuen S;

}

3.3链栈进栈

bool Push(LinkedStack &S,Elemtype x)

{

LinkedStackNode *n=(LinkedStackNode*)malloc(sizeof(LinkedStackNode));

n->data=x;

n->next=S->next;

S->next=n;

return true;

}

3.4链栈出栈

bool Pop(LinkedStack &S,Elemtype &x)

{

if(S->next=NULL)

return false;

LinkedStackNode *n=S->next;

x=n ->data;

S->next=n->next;

free(n);

return true;

}

       其实链栈的出栈进栈可以类比链表的第一个节点删除和头插法建立单链表。

3.5读取栈顶元素

bool GetTop(LinkedStack &S,Elemtype &x)

{

if(S->next==NULL)

return false;

x=S->data;

return true;

}
  • 共享栈

共享栈相对于顺序栈和链栈就比较啰嗦,它是利用栈底不变的特性,让两个栈共享一个一维数组的空间,如下图所示:

4.1共享栈的定义

       共享栈其实就是把两个栈塞进一个数组里,定义代码如下:

#define MaxSize 20

typedef struct

{

Elemtype data[MaxSize];

int top0,top1;

}ShareStack;

4.2共享栈的初始化

       初始化也很简单,就是把栈顶指针变为-1或者MaxSize即可,如下:

void InitStack(ShareStack &S)

{

S.top0=-1;

S.top1=MaxSize;

}

4.3判断共享栈是否满

       如果按照上面方法定义栈顶指针,那么当共享栈满的时候,栈顶指针有一定关系,那就是top0+1=top1:

bool StackFull(ShareStack S)

{

if(S.top0+1==S.top1)

return true;

else

return false;

}

4.4进栈

4.4.1零号栈进栈

       如果是0号栈进栈,那就和正常顺序栈进栈没什么区别,如下:

bool Push0(ShareStack &S,Elemtype x)

{

if(StackFull(S)==true)

return false;

S.data[++S.top0]=x;

return true;

}

4.4.2一号栈进栈

       如果是1号栈进栈,那就得反过来:

bool Push1(ShareStack &S,Elemtype x)

{

if(StackFull(S)==true)

return false;

S.data[--S.top1]=x;

return true;

}

4.5出栈

4.5.1零号栈出栈

bool Pop0(ShareStack &S,Elemtype &x)

{

if(S.top0==-1)

return false;

x=S.data[S.top0--];

return true;

}

4.5.2一号栈出栈

bool Pop1(ShareStack &S,Elemtype &x)

{

if(S.top1==MaxSize)

return false;

x=S.data[S.top1++];

return true;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值