1 前言
栈是一种先进后出的线性表。向一个栈插入新元素可以叫做进栈、入栈、压栈,新元素必须放到栈顶元素上面,使之成为新的栈顶;从一个栈删除元素可以叫做出栈、退栈,它将栈顶元素删除,使和原来栈顶元素相邻的元素称为新的栈顶。出栈和入栈的示意图如下:
2 栈的实现
2.1 栈相关宏定义和枚举类型定义
#define STACK_SIZE 10
#define DATA_TYPE unsigned char
typedef enum
{
STATCK_NULL = 0, /* 栈空 */
STATCK_NOTNULL, /* 栈非空 */
STATCK_FULL, /* 栈满 */
} stack_state_type; /* 栈状态 */
为了便于实现不同数据大小和数量的栈,这里可以使用宏定义DATA_TYPE表示各种类型的数据,使用STACK_SIZE表示栈大小。
2.2 栈结构体定义
typedef struct
{
int stackTop; /* 栈顶指针 */
DATA_TYPE stackBuff[STACK_SIZE]; /* 栈空间 */
} stack_t;
定义一个栈顶指针指示栈顶位置,同时兼具栈大小指示作用。定义一个栈空间,用来保存元素。
2.3 栈相关函数定义
/**
* @brief 初始化栈
*
* @param stack 栈指针
*/
void stack_init(stack_t *stack)
{
stack->stackTop = 0;
}
/**
* @brief 数据入栈
*
* @param stack 栈指针
* @param data 数据
* @return int -1:失败 0:成功
*/
int stack_push(stack_t *stack, DATA_TYPE data)
{
if (stack->stackTop >= STACK_SIZE)
{
return -1;
}
stack->stackBuff[stack->stackTop++] = data;
return 0;
}
/**
* @brief 数据出栈
*
* @param stack 栈指针
* @return int -1:失败 0:成功
*/
int stack_pop(stack_t *stack)
{
if (stack->stackTop <= 0)
{
return -1;
}
stack->stackTop--;
return 0;
}
/**
* @brief 获取栈大小
*
* @param stack 栈指针
*/
int stack_size(stack_t *stack)
{
return stack->stackTop;
}
/**
* @brief 获取栈状态
*
* @param stack 栈指针
* @return stack_state_type 栈状态 STATCK_NULL/STATCK_NOTNULL/STATCK_FULL
*/
stack_state_type stack_state(stack_t *stack)
{
stack_state_type stackState;
if (stack->stackTop == 0)
{
stackState = STATCK_NULL;
}
else if ((stack->stackTop > 0) && (stack->stackTop < STACK_SIZE))
{
stackState = STATCK_NOTNULL;
}
else
{
stackState = STATCK_FULL;
}
return stackState;
}
设计的栈相关函数包括:初始化栈、数据入栈、数据出栈、获取栈大小、获取栈状态5个
3 测试
我们定义一个栈,然后使用2中我们设计的5个函数,最后打印结果看是否和预期一致。测试代码如下:
int main(void)
{
int i;
stack_t stack;
stack_init(&stack);
for (i = 0; i < STACK_SIZE; i++)
{
stack_push(&stack, i + 1);
}
stack_pop(&stack);
stack_pop(&stack);
printf("Stack state : %d\r\n", stack_state(&stack));
printf("Stack size : %d\r\n", stack_size(&stack));
printf("Stack data :");
for (i = 0; i < stack_size(&stack); i++)
{
printf("%d ", stack.stackBuff[i]);
}
printf("\r\n");
return 0;
}
打印结果如下:
结果和我们预期一致,测试成功。