栈的基本概念
栈:栈(stack)是限定仅在表尾进行插入与删除操作的线性表。
特点:后进后出。
栈的作用:栈的引用简化了程序设计的问题,划分了不同关注层次,缩小了思考范围,更加聚焦于我们要解决问题的核心。
栈主要分为顺序栈与链栈。如果栈在使用中元素变化难以预料,最好用链栈,如果变化在可控范围内,建议使用顺序栈。
顺序栈的表示与实现
顺序栈的定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 100
typedef int SElemType;
typedef struct {
SElemType* top; //顺序栈顶指针
SElemType* base; //顺序栈底指针
int stacksize; //顺序栈最大容量
}SqStack;
初始化顺序栈
/* 初始化顺序栈 */
int IintStack(SqStack* S)
{
S->base = (SElemType*)malloc(MAXSIZE * sizeof(SElemType));
if (!S->base) exit(-1); //失败
S->top = S->base; //栈顶指针 = 栈底指针
S->stacksize = MAXSIZE;
return OK;
}
求顺序栈长度
/* 求顺序栈长度 */
int StackLength(SqStack S)
{
return S.top - S.base; // 相差个数
}
清空顺序栈
/* 清空顺序栈 */
int ClearStack(SqStack* S)
{
if (S->base) S->top = S->base; //栈顶指针 = 栈底指针
return OK;
}
顺序栈的入栈
/* 顺序栈的入栈 */
int Push(SqStack* S, SElemType e)
{
if (S->top - S->base == S->stacksize) //栈满了
return ERROR;
*++S->top = e; // S->top++; *S->top = e;
return OK;
}
顺序栈的出栈
/* 顺序栈的出栈 */
int Pop(SqStack* S, SElemType* e)
{
if (S->top == S->base) //空栈
return ERROR;
*e = *S->top--; // *e = *S->top; S->top--;
return OK;
}
销毁顺序栈
/* 销毁顺序栈 */
int DestroyStack(SqStack* S)
{
if (S->base)
{
free(S->base);
S->stacksize = 0;
S->base = S->top = NULL;
}
return OK;
}
链栈(无头结点)的表示与实现
链栈大多数操作与单链表相似,下面我只举出链栈的定义、初始化、进栈和出栈。
链栈的定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int SElemType ;
typedef struct Stacknode {
SElemType data;
struct Stacknode* next;
}Stacknode;
typedef struct Stacknode* LinkStack;
初始化链栈
/* 初始化链栈 */
int InitlinkStack(LinkStack* S_)
{
*S_ = NULL;
return OK;
}
链栈的入栈
/* 链栈的入栈 */
int PushlinkStack(LinkStack* S_, SElemType e)
{
LinkStack p = (LinkStack)malloc(sizeof(Stacknode));
p->data = e;
p->next = *S_; //新结点插入栈顶
*S_ = p; //改变栈顶指针
return OK;
}
链表的出栈
/* 链表的出栈 */
int PoplinkStack(LinkStack* S_, SElemType* e)
{
if ((*S_) == NULL) return ERROR;
*e = (*S_)->data;
LinkStack p = (*S_);
(*S_) = (*S_)->next;
free(p);
return OK;
}