栈的定义
栈是一种后进先出的数据结构。
栈是限制插入和删除只能在一个位置上的线性表。允许删除和插入的一端位于表的末端,叫做栈顶。不允许删除和插入的另一端叫做栈底。对栈的基本操作有push(压栈)和pop(出栈)。
图示:
栈的实现
栈的实现主要包括两种方式:顺序栈和链表栈。
顺序栈
使用数组来实现。
缺点: 需要提前声明一个数组大小。如果数组不够大,就有可能发生越界问题。如果数组过大,则可能浪费一定的空间。
栈的定义实现:
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int top;
}SqStack;
初始化一个空栈
Status InitStack(SqStack *S){
S->top = -1;
return OK;
}
将栈置空
Status ClearStack(SqStack *S){
S->top = -1;
return OK;
}
判断栈是否为空
Status IsEmptyStack(SqStack S){
if (S.top == -1) {
return TRUE;
}
return FALSE;
}
获取栈的长度
int LengthOfStack(SqStack S){
if(IsEmptyStack(S)) return ERROR;
return S.top + 1;
}
栈顶的值
Status ValueOfStack(SqStack S, ElemType *topValue){
if(IsEmptyStack(S)) return ERROR;
*topValue = S.data[S.top];
return OK;
}
栈中插入元素
Status PushStack(SqStack *S, ElemType e){
if (S->top == MAXSIZE -1) {
return ERROR;
}
S->top++;
S->data[S->top] = e;
return OK;
}
栈中删除栈顶元素
Status PopStack(SqStack *S, ElemType *e){
if (S->top == -1) {
return ERROR;
}
*e = S->data[S->top];
S->top -- ;
return OK;
}
遍历打印栈元素
void PrintStack(SqStack S){
printf("打印顺序栈:\n");
while (S.top > -1) {
printf("%d ",S.data[S.top]);
S.top -- ;
}
printf("\n");
}
以上是顺序栈的基本操作。下面讲下链式栈。
链式栈
使用链表来实现栈。内存动态分配,可以不担心内存分配的问题,但是要考虑malloc和free的调用.
链式栈和顺序栈稍有不同,定义链式栈的时候要先定一个链式栈的结构。
typedef struct StackNode{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct
{
LinkStackPtr top;
int count;
}LinkStack;
初始化一个空栈
Status InitStack(LinkStack *S){
S->top = NULL;
S->count = 0;
return OK;
}
把栈置空
Status ClearStack(LinkStack *S){
//链式栈就要考虑free的问题了
LinkStackPtr p,q;
p = S->top;
while (p) {
q = p;
p = p->next;
free(q);
}
//上面已经把S->top变成null了
// S->top = NULL;
S->count = 0;
return OK;
}
是否为空栈
Status IsEmptyLinkStack(LinkStack S){
if (S.count) {
return FALSE;
}
return OK;
}
栈中元素的个数
int LengthOfLinkStack(LinkStack S){
return S.count;
}
获取栈顶元素
Status TopValueOfLinkStack(LinkStack S, ElemType *e){
if (IsEmptyLinkStack(S)) return ERROR;
*e = S.top->data;
return OK;
}
压栈(插入)
Status PushLinkStack(LinkStack *S, ElemType data){
LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
p->data = data;
p->next = S->top;
S->top = p;
S->count ++;
return OK;
}
出栈(删除栈顶)
Status PopLinkStack(LinkStack *S, ElemType *data){
LinkStackPtr p;
if (IsEmptyLinkStack(*S)) {
return ERROR;
}
*data = S->top->data;
p = S->top->next;
S->top = p;
S->count -- ;
free(p);
return OK;
}
遍历栈元素
void printLinkStack(LinkStack S){
printf("打印链式栈!\n");
LinkStackPtr p;
p = S.top;
while (p) {
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
以上为链式栈的基本操作。