栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈是一种后进先出(LIFO)的结构,顺序栈的是连续内存空间下实现的一种数据结构。
(图片转载自网络,侵删)
顺序栈的定义如下:
typedef struct Stack{
int *data, size, top;
}Stack;
其中int *data为栈的数据域,size为数据域的大小。
这里的栈顶元素索引为top - 1, 因此top的初值为0(空栈),满值为size,因此有下面栈的初始化操作↓↓↓
栈的初始化:
Stack *initStack(int n){
Stack *stk = (Stack *)malloc(sizeof(Stack));
stk->data = (int *)malloc(sizeof(int) * n);
stk->top = 0;
stk->size = n;
return stk;
}
栈的清空操作只需要将top指针指向0位置,因此代码实现非常简单(但要注意合法性)
void clearStack(Stack *stk){
if(stk == NULL) return;
stk->top = 0;
return;
}
而相应的,栈的判空操作也只需要判断top是否指向0位置即可
bool empty(Stack *stk){
if(stk == NULL) return false;
return !stk->top;
}
栈的push(入栈),pop(栈顶元素出栈)操作:
bool push(Stack *stk, int val){
if(stk == NULL || stk->size == stk->top) return false;
stk->data[stk->top++] = val;
return true;
}
bool pop(Stack *stk){
if(stk == NULL || empty(stk)) return false;
stk->top--;
return true;
}
两种操作分别在栈非满/空下可进行, 注意栈顶top的偏移.
相应的,栈顶元素即为栈数据域的top - 1位置,这里定义下当栈为空/栈非法时,将返回0元
int top(Stack *stk){
if(stk == NULL || empty(stk)) return 0;
return stk->data[stk->top - 1];
}
还有DEBUG是非常实用的遍历操作!!!
output函数:
void output(Stack *stk){
if(stk == NULL) return;
printf("Stack(%d) = [", stk->top);
for(int i = 0; i < stk->top; i++){
printf(" %d", stk->data[i]);
}
puts("]\n");
return;
}
完整实现如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef struct Stack{
int *data, size, top;
}Stack;
Stack *initStack(int n){
Stack *stk = (Stack *)malloc(sizeof(Stack));
stk->data = (int *)malloc(sizeof(int) * n);
stk->top = 0;
stk->size = n;
return stk;
}
void clearStack(Stack *stk){
if(stk == NULL) return;
stk->top = 0;
return;
}
bool push(Stack *stk, int val){
if(stk == NULL || stk->size == stk->top) return false;
stk->data[stk->top++] = val;
return true;
}
bool empty(Stack *stk){
if(stk == NULL) return false;
return !stk->top;
}
bool pop(Stack *stk){
if(stk == NULL || empty(stk)) return false;
stk->top--;
return true;
}
int top(Stack *stk){
if(stk == NULL || empty(stk)) return 0;
return stk->data[stk->top - 1];
}
void output(Stack *stk){
if(stk == NULL) return;
printf("Stack(%d) = [", stk->top);
for(int i = 0; i < stk->top; i++){
printf(" %d", stk->data[i]);
}
puts("]\n");
return;
}
int main(){
Stack *stk = initStack(100010);
#define MAX_N 110
for(int i = 0; i < MAX_N; i++){
int op = rand() % 3, val = rand() % 100;
if(op == 0)
if(pop(stk))
printf("The top element has been popped\n");
else printf("Failed to pop the top element\n");
else if(push(stk, val))
printf("The %d has been pushed into the stack\n", val);
else puts("Failed to push the elem into the stack\n");
output(stk);
}
return 0;
}