一个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语言 栈 链式结构 实现的更多相关文章

  1. C语言 队列 链式结构 实现

    一个C语言链式结构实现的队列 mQueue (GCC编译). /** * @brief C语言实现的链式队列 * @author wid * @date 2013-10-31 * * @note 若代 ...

  2. C/C++编程笔记:C语言成绩管理系统!链式结构的管理系统源码分享

    最近很多同学因为学校的要求,需要完成自己的那个C语言课程设计,于是就有很多人私信或者加我私聊我,问的最多的还是<学生成绩管理系统>,其实当你项目写多了你就会发现:其实各类的管理系统都离不开 ...

  3. C语言 线性表 双向链式结构 实现

    一个双向链式结构实现的线性表 duList (GCC编译). /** * @brief 线性表双向链表结构 * @author wid * @date 2013-10-28 * * @note 若代码 ...

  4. 数据结构----线性表顺序和链式结构的使用(c)

    PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...

  5. C语言实现链式队列

    链式队列,简称"链队列",即使用链表实现的队列存储结构. 链式队列的实现思想同顺序队列类似,只需创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素, ...

  6. 文件上传以及JS链式结构

    文件上传: 文件上传使用FileUpload控件,使用控件的SaveAs方法,需要绝对路径. 获取文件的绝对路径:Server.MapPath(相对路径); 或许要上传文件的本身名字用.FileNam ...

  7. Javascript、C#、php、asp、python 等语言的链式操作的实现

    一.什么是链式操作 把需要的下一步操作的对象通过上一步操作返回回来.使完成某些功能具有持续性. 二.链式操作优点 代码更精简优雅.链式操作能大大精简代码量,多项操作一行代码一气呵成,搞定: 链式操作应 ...

  8. C语言数据结构-链式队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作

    1.数据结构-链式队列的实现-C语言 typedef struct QNode { int data; struct QNode *next; }QNode,*QueuePtr; typedef st ...

  9. 基于链式链表的栈链式存储的C风格实现

    链式链表的头文件与CPP文件见前文 头文件: #ifndef _LINKSTACK_H_ #define _LINKSTACK_H_ typedef void LinkStack; //创建一个栈 L ...

随机推荐

  1. 解决Cannot modify header information - headers already sent by

    output_buffering = On ,在php.ini中设置.

  2. leetcode刷题: 002 Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  3. 利用should.js进行测试

    nodejs 环境 , 安装should.js包 (npm install should) var should = require('should'); //正确1, 错误0 100 precent ...

  4. 编程实践中C语言的一些常见细节

    对于C语言,不同的编译器采用了不同的实现,并且在不同平台上表现也不同.脱离具体环境探讨C的细节行为是没有意义的,以下是我所使用的环境,大部分内容都经过测试,且所有测试结果基于这个环境获得,为简化起见, ...

  5. c++学习笔记——字面值常量类

    字面值常量类:数据成员都是字面值类型的聚合类是字面值常量类.如果一个类不是聚合类,但是它符合一下要求,则它也是个字面值常量类: 1.数据成员都必须是字面值类型. 2.类必须至少含有一个constexp ...

  6. cs0006 未能找到元数据文件 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

    翻阅了一些资料后发现是需要重新注册IIS服务扩展,在“开始”-“运行”里输入如入命令,回车,搞定 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspne ...

  7. alert/confirm/prompt 处理

    webdriver 中处理JavaScript 所生成的alert.confirm 以及prompt 是很简单的.具体思路是使用switch_to_alert()方法定位到alert/confirm/ ...

  8. android中5大布局

    Android布局也可以用HTML5做,但是用户体验性差 Android布局里XML的属性配置 1. 五种Layout中Item的基础属性: layout_width & layout_hei ...

  9. Ajax2

    一.完整版Ajax $.ajax({ url: "Ashxs/Login.ashx", data: { "name": name, "pwd" ...

  10. Xcode 设置代码不自动换行

    "command + ,"打开设置界面后,找到"Text Editing" 然后选择"Indentation", 最后找到"lin ...