目录
1. 栈的基本概念
栈是一种限定性线性表,是将线性表的插入和删除操作限制为仅在表的一端进行,通常将表中允许进行插入删除的一端称为栈顶(Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器来指示。表的另一端称为栈底(Bottom)。当栈中没有元素时称为空栈。
栈的修改是按后进先出的原则,如元素以 a1,a2,a3,…,an 的顺序进栈,则出栈顺序为 an,…,a3,a2,a1 。每次进栈的元素的元素都被放在原栈顶元素之上而成为新的栈顶,每次出栈的则是当前栈中的栈顶元素,即最后进的元素。
栈主要有两种存储结构:顺序存储结构和链式存储结构。
2. 顺序栈
顺序栈是由顺序存储结构实现的栈,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。利用一个位置指针 top 来动态地指示栈顶元素在顺序栈中的位置, top=-1 即表示空栈。
顺序栈的存储结构及初始化
/*顺序栈的存储结构*/
# define Stack_Size 50
typedef struct {
int elem[Stack_Size]; //用于存放栈中元素的一维数组
int top; //存放栈顶元素的下标,top为-1表示空栈
}SeqStack;
/*初始化顺序栈*/
void InitStack(SeqStack* S) {
S->top = -1;
}
顺序栈 判空、判满
/*判空*/
int IsEmpty(SeqStack* S) {
if (S->top == -1) //栈为空
return TRUE;
else
return FALSE;
}
/*判满*/
int IsFull(SeqStack* S) {
if (S->top == Stack_Size - 1) //栈已满
return TRUE;
else
return FALSE;
}
顺序栈 进栈、出栈、读取栈顶元素
/*顺序栈进栈*/
int Push(SeqStack* S, int x) {
if (S->top == Stack_Size - 1) //栈已满
return FALSE;
S->top++;
S->elem[S->top] = x; //x进栈
return TRUE;
}
/*顺序栈出栈*/
int Pop(SeqStack* S, int *x) {
if (S->top == -1) //栈为空
return FALSE;
*x = S->elem[S->top]; //栈顶元素赋给x
S->top--;
return TRUE;
}
/*读取栈顶元素*/
int GetTop(SeqStack* S, int* x) {
if (S->top == -1) //栈为空
return FALSE;
else {
*x = S->elem[S->top]; //栈顶元素赋给x
return TRUE;
}
}
3. 双端顺序栈(两栈共享技术)
双端顺序栈是一种两栈共享技术。申请一个一个共享的一维数组空间 S[M] ,将两个栈的栈底分别放在一维数组的两端,分别是0、M-1。
双端栈的存储结构及初始化
/*双端顺序栈存储结构*/
# define M 100
typedef struct {
int Stack[M];
int top[2]; //top[0]和top[1]分别为两个栈顶指示器
}DqStack;
/*双端顺序栈初始化*/
void InitStack(DqStack* S) {
S->top[0] = -1;
S->top[1] = M - 1;
}
双端栈 进栈、出栈
/*双端顺序栈的进栈操作*/
int Push(DqStack* S, int x, int i) {
//将数据元素x压入第i号堆栈
if (S->top[0] + 1 == S->top[1]) //栈已满
return FALSE;
switch (i) {
case 0: //压入0号栈
S->top[0]++;
S->Stack[S->top[0]] = x;
break;
case 1: //压入1号栈
S->top[1]--;
S->Stack[S->top[1]] = x;
break;
default:
return FALSE;
}
return TRUE;
}
/*双端顺序栈的出栈操作*/
int Pop(DqStack* S, int *x, int i) {
//从i号堆栈中弹出栈顶元素并送到x中
switch (i) {
case 0: //0号栈出栈
if (S->top[0] == -1) //栈为空
return FALSE;
*x = S->Stack[S->top[0]];
S->top[0]--;
break;
case 1: //1号栈出栈
if (S->top[1] == M) //栈为空
return FALSE;
*x = S->Stack[S->top[1]];
S->top[1]++;
break;
default:
return FALSE;
}
return TRUE;
}
4. 链栈
链栈即采用链表作为存储结构实现的栈,链表的表头指针作为栈顶指针。
链栈的存储结构
/*链栈存储结构*/
typedef struct node {
int data;
struct node* next;
}LinkStackNode;
typedef LinkStackNode* LinkStack;
链栈 进栈、出栈
/*链栈进栈操作*/
int Push(LinkStack LS, int x) {
LinkStackNode* temp;
temp = (LinkStack*)malloc(sizeof(LinkStackNode));
temp->data = x;
temp->next = LS->next;
LS->next = temp; //修改当前栈顶指针
}
/*链栈出栈操作*/
int Pop(LinkStack LS, int* x) {
LinkStackNode* temp;
temp = LS->next;
if (temp == NULL) //栈为空
return FALSE;
LS->next = temp->next;
*x = temp->data;
free(temp);
return TRUE;
}
参考:耿国华《数据结构——用C语言描述(第二版)》