栈——线性表变异体
栈是一种插入和删除都在同一端的线性表。这个同一端叫栈顶
。栈的插入和删除都在同一端,所以最后插入的数据肯定会最先会被取出,这种逻辑结构叫先进后出
——LIFO(Last in first out)
。插入操作叫入栈
,删除操作叫出栈
。
实现栈可以使用数组或链表来实现
使用链表实现代码
- 数据结构
typedef struct _data_node
{
int data;
struct _data_node *prev;
}data_node_t;
typedef struct _link_stack
{
data_node_t *top; //指向栈顶
int stack_size; //栈的大小
int stack_count; //入栈数据计数
}link_stack_t;
- 数据节点的初始化
static data_node_t *data_node_init(int data)
{
data_node_t *d = (data_node_t *)malloc(sizeof(data_node_t));
if(!d)
return NULL;
d->data = data;
d->prev = NULL;
return d;
}
- 数据节点解初始化
static int data_node_deinit(data_node_t *data_node)
{
if(!data_node)
return -1;
data_node->data = 0;
data_node->prev = NULL;
free(data_node);
return 0;
}
- 判断栈是否为空
static int is_stack_empty(link_stack_t *s)
{
return (s->stack_count == 0);
}
- 判断栈是否满
static int is_stack_full(link_stack_t *s)
{
return ( s->stack_count >= s->stack_size );
}
- 初始化栈
int link_stack_init(link_stack_t *s, int stack_size)
{
if(!s)
return -1;
s->top = NULL;
s->stack_count = 0;
s->stack_size = stack_size;
}
- 解初始化栈
int link_stack_deinit(link_stack_t *s)
{
if(!s)
return -1;
if(is_stack_empty(s))
{
s->top = NULL;
s->stack_count = 0;
s->stack_size = 0;
}
else
{
data_node_t *node = s->top;
for(int i = 0; ( (i < s->stack_count) && !node); i++, node = node->prev)
{
data_node_deinit(node);
}
}
return 0;
}
- 入栈
int link_stack_push(link_stack_t *s, int val)
{
if(!s)
return -1;
data_node_t *d = data_node_init(val);
if(!d)
return -1;
if(is_stack_full(s))
return -1;
if(is_stack_empty(s))
{
s->top = d;
s->stack_count++;
return 0;
}
else
{
d->prev = s->top;
s->top = d;
s->stack_count++;
return 0;
}
}
- 出栈
int link_stack_pop(link_stack_t *s, int *val)
{
data_node_t *node;
if(!s)
return -1;
if(is_stack_empty(s))
return -1;
node = s->top; //保存当前要取出的节点
*val = s->top->data; //取出栈中的数据
s->top = node->prev; //栈顶指向下面一个节点
s->stack_count--; //
data_node_deinit(node);
return 0;
}
测试
- 代码
/************************************************************************
* @file: xxx.c
* @author: guangjieMVP
* @github: https://github.com/guangjieMVP
* @version: v1.0.0
* @date: 2020-xx-xx
* @brief:
**************************************************************************/
#include "stdio.h"
#include "link_stack.h"
#include "string.h"
#define LINK_STACK_SIZE 6
link_stack_t link_stack;
int main(int argc, char **argv)
{
int data;
link_stack_init(&link_stack, LINK_STACK_SIZE);
if(link_stack_push(&link_stack, 1) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 2) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 3) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 4) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 5) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 6) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
if(link_stack_push(&link_stack, 7) == -1)
{
printf("push failed\r\n");
}
else
{
printf("push success\r\n");
}
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
link_stack_pop(&link_stack, &data);
printf("%d\r\n",data);
if( link_stack_pop(&link_stack, &data) == (-1) )
{
printf("stack is empty\r\n");
}
else
{
printf("%d\r\n",data);
}
return 0;
}
- 测试结果
可以看到先进
的数据经过出栈的操作后出
。