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 ...
随机推荐
- 一步步编写avalon组件01:弹出层组件
avalon2已经稳定下来,是时候教大家如何使用组件这个高级功能了. 组件是我们实现叠积木开发的关键. avalon2实现一个组件非常轻松,并且如何操作这个组件也比以前的avalon2,还是react ...
- 当前JS文件中加入其他js文件
注意:在html文件导入a.js时,应该把script></script写在/body>后面,否则 document.write()方法有问题. 在载入页面后,浏览器输出流自动关闭: ...
- [python] python 中的" "和' '都是完全转义
dict = {"a" : "apple", "b" : "banana", "g" : " ...
- laravel 数据库迁移
问题:之前有创建迁移文件 并且执行过 如果删除迁移文件 再重新创建迁移文件时就有问题 提示找不到之前的迁移文件 /** 一开始执行的命令 php artisan make:migration crea ...
- 开发板通过UART向主机发送数据
/********************************* 代码功能:开发板通过UART向主机发送数据 使用函数: Serial.begin(数据传输的波特率); Serial.printl ...
- c# SqlHelper Class
using System;using System.Collections;using System.Collections.Generic;using System.Data;using Syste ...
- 关于Android中混淆的问题
1.签名打包后库依赖报错,提示找不到依赖库的方法. 原因:混淆,依赖库的方法被混淆了. 解决方法:过滤混淆,即不要混淆这依赖库的文件. -keep class de.greenrobot.event. ...
- Hex编码字节
1.将字节数组转换为字符串 /** * 将字节数组转换为字符串 * 一个字节会形成两个字符,最终长度是原始数据的2倍 * @param data * @return */ public static ...
- HttpClient请求网络数据的Post请求
new Thread(){ public void run() { try { //获得输入框内容 ...
- 对象转型 casting
一个基类的引用类型变量可以"指向"其子类对象. 一个基类的引用不可以访问其子类对象新增加的成员(属性和方法). 基类强制转型成子类,则能访问子类独有的成员. 可以使用 引用变量in ...