C语言 栈 链式结构 实现
一个C语言链式结构实现的栈 mStack (GCC编译)。
/**
* @brief C语言实现的链式结构类型的栈
* @author wid
* @date 2013-10-30
*
* @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!
*/ #include <stdio.h>
#include <stdlib.h> #define TRUE 1
#define FALSE 0 typedef struct SNODE
{
void *pelm; //元素指针
struct SNODE *next; //指向下一栈节点
}StackNode; typedef struct
{
StackNode *btm; //栈底指针
StackNode *top; //指向栈顶元素
int height; //栈高度
}mStack; //栈方法声明 mStack *CreateStack(); //创建一个空的栈
void DestroyStack( mStack *pStack ); //销毁栈
void ClearStack( mStack *pStack ); //清空栈内元素
int GetHeight( mStack *pStack ); //获取栈高度
int IsEmpty( mStack *pStack ); //检测是否为空栈
int Push( mStack *pStack, void *pdata ); //向栈内压入元素
int Pop( mStack *pStack, void **pdata ); //将栈顶元素出栈
int GetTop( mStack *pStack, void **pdata ); //获取栈顶元素
void ForEachStack( mStack *pStack, void (*func)(void *pdata) ); //从栈顶到栈底的每个元素依次执行 func 函数 //栈方法实现 /**
* @brief 创建一个高度为 nHeight 的栈
*
* @return 返回指向新建的栈的指针
*/
mStack *CreateStack()
{
///创建一个栈
mStack *pStack = (mStack *)malloc( sizeof(mStack) ); ///令栈顶指向栈底指向NULL
pStack->top = pStack->btm = NULL; ///初始栈高度为0
pStack->height = ;
} /**
* @brief 销毁栈 pStack
*
* @param pStack 指向待销毁的栈的指针
*
* @return void
*/
void DestroyStack( mStack *pStack )
{
StackNode *tmp = NULL; ///释放栈内节点
while( tmp != NULL )
{
tmp = pStack->top->next;
free( pStack->top );
pStack->top = tmp;
} ///释放栈
free( pStack );
} /**
* @brief 清空栈内元素
*
* @param pStack 指向待清空元素的栈的指针
*
* @return void
*/
void ClearStack( mStack *pStack )
{
StackNode *tmp = NULL;
while( tmp != NULL )
{
tmp = pStack->top->next;
free( pStack->top );
pStack->top = tmp;
} pStack->top = pStack->btm = NULL; pStack->height = ;
} /**
* @brief 获取栈当前高度
*
* @param 指向待获取高度的栈的指针
*
* @return 返回栈当前高度
*/
int GetHeight( mStack *pStack )
{
return pStack->height;
} /**
* @brief 检测是否为空栈
*
* @param pStack 指向待检测的栈的指针
*
* @return 若为空, 则返回 TRUE, 否则返回 FALSE
*/
int IsEmpty( mStack *pStack )
{
return pStack->height == ? TRUE : FALSE;
} /**
* @brief 向栈内压入元素
*
* @param pStack 待压入元素的栈
* @param pdata 指向待压入栈元素的指针
*
* @return 返回成功入栈后栈的高度
*/
int Push( mStack *pStack, void *pdata )
{
///创建一个栈节点
StackNode *pNode = (StackNode *)malloc( sizeof(StackNode) ); ///为该节点赋值
pNode->pelm = pdata;
pNode->next = pStack->top; ///令栈顶指向最新节点
pStack->top = pNode; ++pStack->height;
} /**
* @brief 将栈顶元素出栈
*
* @param pStack 指向待执行出栈操作的栈的指针
* @param pdata 接收弹出的元素的指针
*
* @return 出栈成功则返回出栈后栈的高度, 否则返回 -1
*/
int Pop( mStack *pStack, void **pdata )
{
///检测是否为空栈
if( pStack->top == pStack->btm )
return -; ///取得栈节点数据元素值
*pdata = pStack->top->pelm; ///将栈顶指针向下退一位
StackNode *p = pStack->top->next;
free( pStack->top );
pStack->top = p; return --pStack->height;
} /**
* @brief 获取栈顶元素到 pt
*
* @param pStack 指向待弹出元素的栈的指针
* @param pdata 指向接收弹出的元素的指针
*
* @return 获取成功则返回栈顶元素的位置, 否则返回 -1
*
* @note 元素位置由 0 计起
*/
int GetTop( mStack *pStack, void **pdata )
{
///检测是否为空栈
if( pStack->height == )
return -; *pdata = pStack->top->pelm; return pStack->height - ;
} /**
* @brief 从栈底到栈顶的每个元素依次执行 func 函数
*
* @param pStack 指向待处理的栈的指针
* @param func 需要执行的函数的指针
*
* @return void
*/
void ForEachStack( mStack *pStack, void (*func)(void *pt) )
{
StackNode *tmp = pStack->top;
while( tmp != NULL )
{
func( tmp->pelm );
tmp = tmp->next;
}
} void display( void *pn )
{
printf( "%d ", *(int *)pn );
} int main()
{
int a = , b = , c = , n = ;
void *pa = NULL; ///测试 CreateStack
mStack *psk = CreateStack(); ///测试 IsEmpty、GetHeight
if( IsEmpty(psk) == TRUE )
printf( "Init Height = %d\n", GetHeight(psk) ); ///测试 Push
printf("压入数字 10\n"); Push( psk, &a );
printf("压入数字 20\n"); Push( psk, &b );
printf( "压入2元素后栈高度 = %d\n", GetHeight(psk) ); ///测试 Pop
printf( "\n测试 Pop:\n" );
n = Pop( psk, &pa );
if( n != - )
printf( "Pop = %d\n", *(int *)pa ); n = Pop( psk, &pa );
if( n != - )
printf( "Pop = %d\n", *(int *)pa ); n = Pop( psk, &pa );
if( n != - )
printf( "Pop = %d\n", *(int *)pa ); ///测试清空栈
Push( psk, &a );
printf("\n清空栈..");
ClearStack( psk );
printf( "\n清空后栈高度 = %d\n", GetHeight(psk) ); ///测试 ForEachStack
printf("\n\压入3元素..");
Push( psk, &a );
Push( psk, &b );
Push( psk, &c );
printf("\n测试 ForEachStack: "); ForEachStack( psk, display ); ///测试GetTop
printf("\n测试GetTop:\n");
n = GetTop( psk, &pa );
if( n != - )
printf( "GetTop = %d\n", *(int *)pa ); ///再次输出当前栈高度
printf( "\n当前栈高度Height = %d\n", GetHeight(psk) ); ///测试 DestroyStack
printf("\n销毁栈..\n");
DestroyStack( psk ); return ;
}
测试运行:

若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢。
C语言 栈 链式结构 实现的更多相关文章
- C语言 队列 链式结构 实现
		
一个C语言链式结构实现的队列 mQueue (GCC编译). /** * @brief C语言实现的链式队列 * @author wid * @date 2013-10-31 * * @note 若代 ...
 - C/C++编程笔记:C语言成绩管理系统!链式结构的管理系统源码分享
		
最近很多同学因为学校的要求,需要完成自己的那个C语言课程设计,于是就有很多人私信或者加我私聊我,问的最多的还是<学生成绩管理系统>,其实当你项目写多了你就会发现:其实各类的管理系统都离不开 ...
 - C语言 线性表 双向链式结构 实现
		
一个双向链式结构实现的线性表 duList (GCC编译). /** * @brief 线性表双向链表结构 * @author wid * @date 2013-10-28 * * @note 若代码 ...
 - 数据结构----线性表顺序和链式结构的使用(c)
		
PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...
 - C语言实现链式队列
		
链式队列,简称"链队列",即使用链表实现的队列存储结构. 链式队列的实现思想同顺序队列类似,只需创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素, ...
 - 文件上传以及JS链式结构
		
文件上传: 文件上传使用FileUpload控件,使用控件的SaveAs方法,需要绝对路径. 获取文件的绝对路径:Server.MapPath(相对路径); 或许要上传文件的本身名字用.FileNam ...
 - Javascript、C#、php、asp、python 等语言的链式操作的实现
		
一.什么是链式操作 把需要的下一步操作的对象通过上一步操作返回回来.使完成某些功能具有持续性. 二.链式操作优点 代码更精简优雅.链式操作能大大精简代码量,多项操作一行代码一气呵成,搞定: 链式操作应 ...
 - C语言数据结构-链式队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
		
1.数据结构-链式队列的实现-C语言 typedef struct QNode { int data; struct QNode *next; }QNode,*QueuePtr; typedef st ...
 - 基于链式链表的栈链式存储的C风格实现
		
链式链表的头文件与CPP文件见前文 头文件: #ifndef _LINKSTACK_H_ #define _LINKSTACK_H_ typedef void LinkStack; //创建一个栈 L ...
 
随机推荐
- 初识Memcached
			
一,什么是memcached? Memcached是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库负载..它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱 ...
 - 邮件江湖群狼环伺 U-Mail邮件系统防狼有术
			
小时候听过一首儿歌<小兔子乖乖>,里面说到有条恶狼,常常冒充小兔子的“妈妈”,要求小兔 子开门,但小兔子谨守妈妈的训诫,就是不开门,直到辨别出妈妈在窗外的声音,才打开房门.如果我们将一些似 ...
 - Visio控件关闭“形状”面板
			
Visio.Window winShapeSearch = axDrawingControl1.Window.Windows.get_ItemFromID((int)Visio.VisWinTypes ...
 - html-5 --html5教程article、footer、header、nav、section使用
			
header header元素是一种具有引导和导航作用的辅助元素.通常,header元素可以包含一个区块的标题(如h1至h6,或者hgroup元素标签),但也可以包含其他内容,例如数据表格.搜索表单或 ...
 - 管理权限<八>
			
权限:如果用户要访问其它方案的对象,则必须为其授予对象的权限.为权限  权限 权限是指执行特定类型 sql 命令或是访问其它方案对象的权利,包括系统权限和对象权限两种. 系统权限  系统权限介绍 ...
 - CDN在中国的发展的九个年头的点点滴滴
			
对于发展快速的互联网行业来说,8年时间已经足够让一个产业跌宕起伏.但CDN在国内的发展却没有大红大紫,直到2005... 对于发展快速的互联网行业来说,8年时间已经足够让一个产业跌宕起伏.但CDN在国 ...
 - 【Java】XML解析之SAX
			
SAX介绍 SAX(Simple API for XML)是一种事件驱动的流式XML文件处理方式,区别与DOM方式的是不需要在内存中建一棵DOM树,而是根据读取XML时遇到的标签事件来顺序处理,因此具 ...
 - UWP深入学习三:依赖属性、附加属性和数据绑定
			
Dependency properties overview Custom dependency properties Attached properties overview Custom atta ...
 - 有关pascal的填充语句小技巧
			
背景 今天打代码,用了一次fillchar(a,sizeof(a),1); 结果a数组(of longint)所赋的值却不是1 探索 ···pascal program fillchartest; v ...
 - 关于GP的理解
			
连续式中,CMMI有5个GG:阶段式只有3个.多出来的2个GG,一个对应的是阶段4的量化,一个是阶段5的持续优化,确保了阶段式和连续式在范围上的一致性. GG就是讲各个过程中的共有元素抽取出来,形成的 ...