一、栈
栈是一种数据存储结构,栈是限定仅在表尾进行插入与删除操作的线性表。简单的来说栈中的元素都是遵从先进后出,后进先出的原则。在日常生活中,例如我们在浏览器上网时,点击前进了好几次,相当于往栈里面插入了几次。假如点击返回,浏览器会转到最近一个我们浏览过的网页,后进去的现出来,这就利用了栈结构。
我们把允许插入的一端称为栈顶(top),而另一端称为栈底(bottom)。栈有被称为后进先出(last in first out)的线性表,简称LIFO结构。
栈的插入操作,叫作进栈,也称为压栈、入栈。栈的删除操作,叫作出栈,也可叫作弹栈。
1、栈的顺序存储结构及实现
我们定义下标为0的一端为栈底,我们再定义变量top来表示栈顶元素的位置,下面可以用c++语言定义栈结构:
当栈为空栈时,我们定义top为-1。
下面给出,判断栈空函数与压栈弹栈操作。判断栈空即当top=-1时,当前栈为空。
在进行压栈时,首先需要要判断当前栈是否已满,即当top是否小于等于顺序表最大容量,才能够进行压栈操作。
在进行弹栈时,首先需要判断当前栈是否为空,若不为空,即可进行弹栈操作。
#include <stdio.h>
typedef int ElemType;
#define MAXSIZE 10
typedef struct
{
ElemType data[MAXSIZE];
int top;
}SqStack;
bool StackEmpty(SqStack* s1)//因为结构体较大,我们只需传结构体的指针就ok了,提高了效率。
{
return s1->top == -1 ? true : false;
}
bool Push(SqStack* s1,ElemType e)
{
if (s1->top == MAXSIZE - 1)
return false;
s1->top += 1;
s1->data[s1->top] = e;
}
bool Pop(SqStack* s1, ElemType* e)
{
if (s1->top == -1)
return false;
*e = s1->data[s1->top];
s1->top -= 1;
}
2、栈的链式存储结构
栈的链式存储结构,简称链栈。使用链式存储结构的优点,可以不用担心栈满。链栈的栈底为头指针,链栈的栈顶为链表最后一个结点的地址。
下面是关于链栈的定义及压栈与弹栈操作:
#include <stdio.h>
typedef int ElemType;
typedef struct _StackNode
{
ElemType data;
_StackNode* next;
}StackNode;
typedef StackNode* LinkStackPtr;
typedef struct _LinkStack
{
LinkStackPtr top;
LinkStackPtr head;
int count;
}LinkStack;
bool Push(LinkStack* s1, ElemType e)
{
LinkStackPtr new1 = (LinkStackPtr)malloc(sizeof(StackNode));
new1->data = e;
new1->next = NULL;
s1->count++;
if (s1->top == NULL)
{
s1->top = new1;
s1->head = new1;
return true;
}
else
{
s1->top->next = new1;
s1->top = new1;
return true;
}
}
bool Pop(LinkStack* s1,ElemType* e)
{
if (s1->top == NULL)
{
return false;
}
*e = s1->top->data;
if (s1->top == s1->head)
{
free(s1->top);
s1->top = NULL;
s1->head = NULL;
}
else
{
LinkStackPtr pPos = s1->head;
while (pPos->next != s1->top)
{
pPos = pPos->next;
}
free(s1->top);
s1->top = pPos;
pPos->next = NULL;
}
return true;
}
由于是链式结构,所以首先定义了链表结点。再定义了链栈结构。链栈结构包括top指针,头指针,与结点个数。
关于压栈(入栈)操作,先用malloc申请新的结点空间new1,把需要入栈的元素值赋new1的数据域,并且让new1的指针域为空、count++,当栈为空时,把new1赋给top,把new1赋给head。当栈不为空时,把new1赋给top的next域,然后将new1赋给top。这样就完成了入栈操作。