目录
一、栈的概念
应用场景:关于子弹上膛、发射的顺序我们都知道,最先上膛的子弹会在最后射出,而最后上膛的子弹最先射出。这就是栈的一个特性:先进后出。
二、基本实现逻辑
1、接口设计
使用单向链表来实现栈。
定义 Node 作为栈节点,包含数据 data,以及 next 指针指向下一个栈节点。
定义 Stack 作为栈的操作入口,包含栈节点个数。
/* 宏定义 */
#define RET_INT_SUCC (0)
#define RET_INT_FAIL (-1)
#define RET_BOOL_TRUE true
#define RET_BOOL_FALSE false
/* 结构体的设计 */
typedef struct NODE
{
int data; // 存储栈元素数据
struct NODE *next; // 指向下一个节点的指针
}Node;
typedef struct
{
Node *headNode;
int size;
}Stack;
/* 函数声明/接口设计 */
// 初始化栈
Stack *initStack();
// 判断栈是否为空
bool isEmpty(Stack *s);
// 入栈操作
int push(Stack *s, int value);
// 出栈操作
int pop(Stack *s);
// 获取栈顶元素
int getTop(Stack *s);
// 销毁/释放栈
int destroyStack(Stack *s);
2、接口实现
/* 接口实现 */
// 初始化栈
Stack *initStack()
{
Stack *s = calloc(1, sizeof(Stack));
if(NULL == s)
return NULL;
s->headNode = NULL;
s->size = 0;
return s;
}
// 判断栈是否为空
bool isEmpty(Stack *s)
{
if(NULL == s)
return RET_BOOL_FALSE;
if(NULL == s->headNode)
return RET_BOOL_TRUE;
return RET_BOOL_FALSE;
}
// 入栈操作
int push(Stack *s, int value)
{
Node *newNode = NULL;
if(NULL == s)
return RET_INT_FAIL;
// create newNode
newNode = calloc(1, sizeof(Node));
newNode->data = value;
newNode->next = NULL;
// push
if(isEmpty(s))
{
s->headNode = newNode;
goto PUSH_SUCC;
}
newNode->next = s->headNode;
s->headNode = newNode;
PUSH_SUCC:
printf("push(%d)\n", newNode->data);
s->size ++;
return RET_INT_SUCC;
}
// 出栈操作
int pop(Stack *s)
{
Node *delNode = NULL;
if(isEmpty(s))
return RET_INT_FAIL;
delNode = s->headNode;
s->headNode = delNode->next;
printf("pop(%d)\n", delNode->data);
free(delNode);
s->size --;
return RET_INT_SUCC;
}
// 获取栈顶元素
int getTop(Stack *s)
{
if(NULL == s)
return -1;
if(isEmpty(s))
return -1;
return s->headNode->data;
}
// 销毁/释放栈
int destroyStack(Stack *s)
{
if(NULL == s)
return RET_INT_FAIL;
while(!isEmpty(s))
pop(s);
free(s);
return RET_INT_SUCC;
}
3、接口验证
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* 主函数 */
int main(void)
{
Stack *s = initStack();
if(NULL == s)
return RET_INT_FAIL;
push(s, 10);
push(s, 20);
push(s, 30);
push(s, 40);
push(s, 50);
printf("栈顶元素:%d\n", getTop(s)); // 输出栈顶元素
pop(s);
printf("出栈后栈顶元素:%d\n", getTop(s)); // 再次输出栈顶元素
destroyStack(s);
return RET_INT_SUCC;
}
编译 && 执行:
注:一个使用单向链表实现栈的可视化链接:Linked List Stack Visualization