创建通用的非循环单向动态链表栈

5 篇文章 0 订阅
3 篇文章 0 订阅

栈的应用场景非常多,系统的函数调用栈、逆序匹配、数制转换、迷宫求解等等,本文介绍介绍使用链表实现、具有通用性的栈

功能需求

  1. 判空
  2. 判满
  3. 入栈
  4. 出栈
  5. 销毁栈
  6. 输出打印

数据结构

使用预编译宏作为开关,实现数据结构成员通用性

/*------------------common linked stack Start----------------*/
#define TEST_COM_LNK_STACK 1
#define MAZE_STACK_SUPPORT 0
typedef struct stCustomData {
	/*customized member here*/
	/*...*/
	/*customized member here*/
#if TEST_COM_LNK_STACK
	stElemtype_singleLL stData;
#elif MAZE_STACK_SUPPORT
	stMazeNode stData;
#endif
}stCustomData, *pstCustomData;
typedef struct stComLnkStackNode {
	stCustomData stElm;
	stComLnkStackNode *pstNxt;
}stComLnkStackNode, *pstComLnkStackNode, **ppstComLnkStackNode;
typedef struct stComLnkStack {
	PP_INT32 iSize;
	PP_INT32 iVol;
	pstComLnkStackNode pstTop;
	pstComLnkStackNode pstBottom;
}stComLnkStack, *pstComLnkStack, **ppstComLnkStack;
/*------------------common linked stack End----------------*/

接口列表

为了提升性能,减少不必要的调用,使用宏替代函数实现判满、判空;同时为了让链式栈更具有通用性,尽量让用户(自己)能有更多精力去考虑业务而不是底层实现,也把内存申请封装成为了一个宏,所有的接口如下:

/*********************common linked stack Start*********************/
#define COM_LINK_GET_TOP(pstStk) ((pstStk)->pstTop)
#define COM_LINK_STACK_EMPTY(pstStk) (!(pstStk)->pstTop ? TRUE : FALSE)
#define COM_LINK_STACK_FULL(pstStk) ((pstStk)->iSize + 1 > (pstStk)->iVol ? TRUE : FALSE)
#define NULL_PTR(pstTmp) ((pstTmp) = NULL)
#define COM_LNK_STACK_NODE_MALLOC(pstCur)	\
	pstComLnkStackNode pstCur = (pstComLnkStackNode)malloc(sizeof(stComLnkStackNode));\
	if (!(pstCur))	RET_LOCAL(enRetVal = ERR_MEMORY_ALLOC);\
	memset((pstCur),0,sizeof(stComLnkStackNode));
enErr_val CreateComLnkStack(ppstComLnkStack ppstStk, int iVolume);
enErr_val PushComLnkStack(const pstComLnkStack pstStk, const pstComLnkStackNode pstElm);
enErr_val PopComLnkStack(const pstComLnkStack pstStk, ppstComLnkStackNode ppstElm);
enErr_val DestroyComLnkStack(ppstComLnkStack ppstStk);
void PrintComLnkStack(const pstComLnkStack pstStk);
/*********************common linked stack End*********************/

接口实现

创建和初始化链式栈

enErr_val CreateComLnkStack(ppstComLnkStack ppStk, int iVol) {
	REG_FUNC_NAME("CreateComLnkStack");
	enErr_val enRetVal = ERR_SUCCESS;
	if (*(ppStk))	*ppStk = NULL;
	*ppStk = (pstComLnkStack)malloc(iVol * sizeof(stComLnkStack));
	if (!(*ppStk)) RET_LOCAL(enRetVal = ERR_MEMORY_ALLOC);
	(*ppStk)->iVol = iVol;
	(*ppStk)->iSize = 0;
	(*ppStk)->pstTop = NULL;
	(*ppStk)->pstBottom = NULL;
	RET_LOCAL(enRetVal)
}

入栈操作

入栈前需要判满,若栈满则退出并报错;

enErr_val PushComLnkStack(const pstComLnkStack pStk, const pstComLnkStackNode pElm) {
	REG_FUNC_NAME("PushComLnkStack");
	enErr_val enRetVal = ERR_SUCCESS;
	if (!pStk || !pElm) RET_LOCAL(enRetVal = ERR_INVALID_PARAMETER);
	if (COM_LINK_STACK_FULL(pStk)) RET_LOCAL(enRetVal = ERR_STACK_FULL);
	pElm->pstNxt = COM_LINK_GET_TOP(pStk);
	pStk->pstTop = pElm;
	++pStk->iSize;
	RET_LOCAL(enRetVal)
}

出栈操作

出栈前要判空,若栈空则退出并报错;

enErr_val PopComLnkStack(const pstComLnkStack pStk, ppstComLnkStackNode ppElm) {
	REG_FUNC_NAME("PopComLnkStack");
	enErr_val enRetVal = ERR_SUCCESS;
	if (!pStk || !ppElm) RET_LOCAL(enRetVal = ERR_INVALID_PARAMETER);
	if (COM_LINK_STACK_EMPTY(pStk)) RET_LOCAL(enRetVal = ERR_STACK_EMPTY);
	(*ppElm) = COM_LINK_GET_TOP(pStk);
	pStk->pstTop = (*ppElm)->pstNxt;
	--pStk->iSize;
	RET_LOCAL(enRetVal)
}

销毁栈

enErr_val DestroyComLnkStack(ppstComLnkStack ppStk) {
	REG_FUNC_NAME("DestroyComLnkStack");
	enErr_val enRetVal = ERR_SUCCESS;
	if (!(*ppStk)) RET_LOCAL(enRetVal = ERR_INVALID_PARAMETER);
	pstComLnkStackNode stuff = NULL;
	while (!COM_LINK_STACK_EMPTY(*ppStk)) {
		PopComLnkStack(*ppStk, &stuff);
		free(stuff);
	}
	NULL_PTR(stuff);
	free(*ppStk);
	PP_LOG("the stack is destory!\n");
	RET_LOCAL(enRetVal)
}

打印输出

void PrintComLnkStack(const pstComLnkStack pStk) {
	REG_FUNC_NAME("PrintComLnkStack");
	if (!pStk)	return;
	pstComLnkStackNode pNode = COM_LINK_GET_TOP(pStk);
	PP_INT32 i = 0;
	while (pNode) {
#if TEST_COM_LNK_STACK
		PP_LOG("%d-th:%d, pstNxt addr:%x\n",
			++i, pNode->stElm.stData.iScores, pNode->pstNxt);
#endif
		pNode = pNode->pstNxt;
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值