概述
栈特点
- 本质是操作受限的线性表,只能在一端进行插入删除操作
- 后进先出(LIFO)
用途
- 模拟递归
- 深度优先遍历,实现DFS
- 中缀表达式求值
- 求任意两个成员的关系(如括号匹配问题,先用栈预处理)
设计数据结构
//链栈结点
typedef struct Node {
TYPENAME _data;
struct Node *_pNext;
}Node_t, *pNode_t;
//链栈
typedef struct Stack {
pNode_t _pHead; //栈顶指针
int _size; //栈大小
}Stack_t, *pStack_t;
单向链表的相关操作
- 初始化
- 判空
- 销毁(销毁堆空间)
- 压栈
- 弹栈
- 查看栈顶
操作实现步骤
初始化(参数:栈地址)
- 置空
判空(参数:栈地址)
- return 0 == size;
销毁(参数:栈地址)
- 栈大小不为0时,依次释放结点
压栈(参数:栈地址,新元素)
- 新建结点并初始化,头插入链表
- ++size
弹栈(参数:栈地址)
-
如果栈空,报错返回
-
如果栈非空,保存栈顶指针,修改栈顶,释放原栈顶节点
查看栈顶(参数:栈地址)
- 如果栈空,报错返回
- 如果栈非空,返回栈顶元素
代码
头文件 LinkStack.h
#ifndef __SEQSTACK_HPP
#define __SEQSTACK_HPP
#define TYPENAME int
//链栈结点
typedef struct Node {
TYPENAME _data;
struct Node *_pNext;
}Node_t, *pNode_t;
//链栈
typedef struct Stack {
pNode_t _pHead; //栈顶指针
int _size; //栈大小
}Stack_t, *pStack_t;
void stack_init(pStack_t pSt);
void stack_destroy(pStack_t pSt);
int stack_empty(pStack_t pSt);
int stack_push(pStack_t pSt, TYPENAME val);
int stack_pop(pStack_t pSt);
void stack_show(pStack_t pSt);
//使用前需判断有无元素
TYPENAME stack_top(pStack_t pSt);
#endif
实现文件 LinkStack.c
#include "LinkStack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void stack_init(pStack_t pSt)
{
pSt->_pHead = NULL;
pSt->_size = 0;
}
void stack_show(pStack_t pSt)
{
if (!stack_empty(pSt)) {
pNode_t pCur = pSt->_pHead;
for (; pCur; pCur = pCur->_pNext) {
printf("%d ", pCur->_data);
}
printf("\n");
}
}
void stack_destroy(pStack_t pSt)
{
if (!stack_empty(pSt)) {
for (pNode_t pCur = pSt->_pHead; pCur; pCur = pCur->_pNext)
{
pNode_t pDel = pCur;
free(pDel);
pDel = NULL;
}
memset(pSt, 0, sizeof(Stack_t));
}
}
int stack_empty(pStack_t pSt)
{
return 0 == pSt->_size;
}
int stack_push(pStack_t pSt, TYPENAME val)
{
pNode_t pNew = (pNode_t)calloc(1, sizeof(Node_t));
pNew->_data = val;
pNew->_pNext = NULL;
pNew->_pNext = pSt->_pHead;
pSt->_pHead = pNew;
++pSt->_size;
return 0;
}
int stack_pop(pStack_t pSt)
{
if (!stack_empty(pSt)) {
pNode_t pDel = pSt->_pHead;
pSt->_pHead = pDel->_pNext;
free(pDel);
pDel = NULL;
--pSt->_size;
return 0;
}
printf("Stack is empty, cannot pop!\n");
return -1;
}
//使用前需判断有无元素
TYPENAME stack_top(pStack_t pSt)
{
return pSt->_pHead->_data;
}
测试文件 test_linkstack.c
#include "LinkStack.h"
#include <stdio.h>
void test0()
{
Stack_t st;
stack_init(&st);
printf("\n-----------test stack_push------------\n");
stack_push(&st, 4);
stack_push(&st, 5);
stack_push(&st, 3);
stack_push(&st, 9);
stack_push(&st, 4);
stack_push(&st, 5);
stack_push(&st, 3);
stack_push(&st, 9);
if (!stack_empty(&st)) {
printf("st.top = %d\n", stack_top(&st));
}
printf("st.size = %d\n", st._size);
stack_show(&st);
printf("\n-----------test stack_push------------\n");
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
stack_pop(&st);
if (!stack_empty(&st)) {
printf("st.top = %d\n", stack_top(&st));
}
printf("st.size = %d\n", st._size);
stack_show(&st);
stack_destroy(&st);
}
int main()
{
test0();
return 0;
}