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 ...
随机推荐
- Explode TArray
function Explode(const Separator, S: string; Limit: Integer = 0): TArray;var SepLen : Integer; F, P ...
- nginx配置文件注释
#定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_processes 8; #全局错误日志定义类型,[ debug | in ...
- JDK 环境变量设置
.net转JAVA了.记心不好,记录一下. 安装好jdk(64位)后找到我的电脑(右键)>属性>高级选项卡>环境变量>,里面有管理员的用户变量,有系统变量.我选的是系统变量.点 ...
- (转)UVM内容梗概
1. 类: 面向对象基础传统的面向对象编程与systemverilog类的特点,类的定义,成员与方法,构造函数,对象的复制和深/浅拷贝,父类/子类关系,类的继承,作用域的规则,对象的句柄以及赋值,方法 ...
- JS出现illegal character非法字符提示
引用js文件,js文件内的汉字在页面显示乱码 解决方式: a. 保持js文件编码与jsp页面编码格式一致: b. 在引入js文件时,在script中添加charset=""属性,指 ...
- 如何在其他电脑上运行VS2005编译的DEBUG版应用程序
做项目的过程中,遇到这样的问题:在自己的电脑上用VS2005编译好的DEBUG版程序在其它的没有安装VS2005的电脑上没有办法运行,郁闷至极啊. 直 接拷贝文件后,错误信息如下:"This ...
- NGUI 使用UITable(或UIGrid)注意事项
在ScrollView显示区域中,若Item数量不足以超出显示区域,有可能不是贴着ScrollView最边缘位置显示!这个时候可以按如下方法调整: 因为实际情况中,往ScrollView中添加Item ...
- HDU 3974 Assign the task(dfs建树+线段树)
题目大意:公司里有一些员工及对应的上级,给出一些员工的关系,分配给某员工任务后,其和其所有下属都会进行这项任务.输入T表示分配新的任务, 输入C表示查询某员工的任务.本题的难度在于建树,一开始百思不得 ...
- (转)SqlBulkCopy批量复制数据
在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还是进行不同数据源之间的迁移,都不是很方便.而 在.Net2.0中,SQLClient命名空间下增加了几个新类帮助我们 ...
- hdu 3254 (状压DP) Corn Fields
poj 3254 n乘m的矩阵,1表示这块区域可以放牛,0,表示不能,而且不能在相邻的(包括上下相邻)两个区域放牛,问有多少种放牛的方法,全部不放也是一种方法. 对于每块可以放牛的区域,有放或者不放两 ...