队列和栈作为一种最简单最基本的常用数据结构,可以说在许多方面都应用广泛。在程序运行时,他们可以保存程序运行路径中各个点的信息,以便用于回溯操作或其他需要访问已经访问过的节点信息的操作。这里对栈的特点、作用做出描述、并简单地用不同途径实现了栈的基本功能。本文的实现分别用了C语言(不是纯C,仍为cpp文件,仅仅只是采用了C语言中的部分思想)和C++,代码均在GCC编译器下验证通过。
什么是栈?
栈是一种先进后出(FILO)的数据结构,与上一篇中的队列一样,同为最基础的数据结构之一。队列请参考常用数据结构——队列及其应用。详细定义请参考教科书。栈同样作为一种限制性的线性表。操作只能在一端进行,即栈顶。另一端为栈底,不进行操作。在栈顶插入元素的操作称为压栈或进栈(push),删除元素的操作称为出栈(pop)。
栈的结构类似于一个箱子,装入东西只能从上面加在最顶上,取出时也只能先取出箱子中最顶上的东西。
基本操作除了出栈,压栈外,还有取栈顶元素,初始化,销毁,判空,判满,清空,遍历等操作,可根据需求定义。类似于队列,栈对应于顺序存储结构和链式存储结构分别为顺序栈和链式栈。
C实现
顺序栈在C语言中的实现很简单:
其中栈顶指针top指向栈顶元素。
#include<iostream>
#include<stdlib.h>
#define MaxSize 100
using namespace std;
typedef struct//栈的定义
{
char data[MaxSize];//默认字符数组
int top;//指针
}SqStack;
void InitStack(SqStack *&s);//初始化
void DestroyStack(SqStack *&s); //销毁栈
bool StackEmpty(SqStack *s);//判空
bool Push(SqStack *&s,char e);//压栈
bool Pop(SqStack *&s,char &e); //出栈
bool GetTop(SqStack *s,char &e);//取得栈顶元素
int main(void)
{
SqStack *s;
InitStack(s);
DestroyStack(s);
system("pause");
return 0;
}
void InitStack(SqStack *&s)
{
s = (SqStack *)malloc(sizeof(SqStack));
s->top = -1;
}
void DestroyStack(SqStack *&s)//销毁栈
{
free(s);
}
bool StackEmpty(SqStack *s)//判空
{
return s->top == -1;
}
bool Push(SqStack *&s,char e)//压栈
{
if(s->top == MaxSize-1)//栈满情况
return false;
s->top ++;
s->data[s->top] = e;//e赋给栈顶
return true;
}
bool Pop(SqStack *&s,char &e)//出栈
{
if(s->top == -1)//为空
return false;
e = s->data[s->top];
s->top --;
return true;
}
bool GetTop(SqStack *s,char &e)//取栈顶元素
{
if(s->top == -1)
return false;
e = s->data[s->top];
return true;
}
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct SNode
{
int data;
SNode *next;
}LinkedStack;//链式栈节点定义
void InitStack(LinkedStack *&s);//初始化
void DestroyStack(LinkedStack *&s);//销毁栈
bool StackEmpty(LinkedStack *s);//判空
void Push(LinkedStack *&s,int e);//压栈/进栈
bool Pop(LinkedStack *&s,int &e);//出栈
bool GetTop(LinkedStack *&s,int &e);//get栈顶元素
int main(void)
{
LinkedStack *Q;
InitStack(Q);
Push(Q,1);
Push(Q,2);
Push(Q,3);
int a,b;
Pop(Q,a);