一个能够自动扩容的顺序结构的栈 ArrStack 实例 (GCC编译)。

 /**
* @brief C语言实现的顺序结构类型的栈
* @author wid
* @date 2013-10-29
*
* @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!
*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define TRUE 1
#define FALSE 0 typedef struct Point2D
{
int x;
int y;
}ElemType; //栈元素结构 typedef struct
{
ElemType *btm; //栈底
ElemType *top; //栈顶
int height; //栈高
int size; //栈总大小
}ArrStack; //栈结构 //栈方法声明
ArrStack *CreateStack( int nSize ); ///创建一个大小为nSize的栈
void DestroyStack( ArrStack *pStack ); ///销毁栈 pStack
void ClearStack( ArrStack *pStack ); ///清空栈 pStack 内的元素
int GetHeight( ArrStack *pStack ); ///获取栈 pStack 的高度
int GetSize( ArrStack *pStack ); ///获取栈 pStack 的总容量
int IsEmpty( ArrStack *pStack ); ///检测栈 pStack 是否为空栈
int Push( ArrStack *pStack, ElemType *pt ); ///将元素 pt 压入栈 pStack
int Pop( ArrStack *pStack, ElemType *pt ); ///将栈顶元素出栈到 pt
int GetTop( ArrStack *pStack, ElemType *pt ); ///获取栈顶元素到 pt
void ForEachStack( ArrStack *pStack, void (*func)(ElemType *pt) ); ///从栈底到栈顶的每个元素依次执行 func 函数
void ReForEachStack( ArrStack *pStack, void (*func)(ElemType *pt) ); ///从栈顶到栈底的每个元素依次执行 func 函数 //栈方法实现 /**
* @brief 创建一个大小为 nSize 的栈
*
* @param nSize 栈的初始大小
*
* @return 返回指向创建的栈的指针
*
* @note nSize 初始大小需大于0
*/
ArrStack *CreateStack( int nSize )
{
//根据栈结构创建一个栈
ArrStack *pStack = (ArrStack *)malloc( sizeof(ArrStack) ); //申请栈初始空间
pStack->btm = (ElemType *)calloc( nSize, sizeof(ElemType) ); //令栈顶指向栈底元素
pStack->top = &pStack->btm[]; //初始化栈高度为 0
pStack->height = ; //初始化栈大小为初始大小
pStack->size = nSize; return pStack;
} /**
* @brief 销毁栈 pStack
*
* @param pStack 指向待销毁的栈的指针
*
* @return void
*/
void DestroyStack( ArrStack *pStack )
{
//释放栈内元素
free( pStack->btm ); //释放栈
free( pStack );
} /**
* @brief 清空栈内元素
*
* @param pStack 指向待清空元素的栈的指针
*
* @return void
*/
void ClearStack( ArrStack *pStack )
{
//令栈顶指向栈底
pStack->top = &pStack->btm[]; //将栈高度置为 0
pStack->height = ;
} /**
* @brief 获取栈 pStack 的高度
*
* @param pStack 指向待获取高度的栈的指针
*
* @param 返回当前栈的高度
*/
int GetHeight( ArrStack *pStack )
{
return pStack->height;
} /**
* @brief 获取栈 pStack 的总容量
*
* @param pStack 指向待获取总容量的栈的指针
*
* @return 返回栈的当前总容量
*/
int GetSize( ArrStack *pStack )
{
return pStack->size;
} /**
* @brief 检测栈 pStack 是否为空栈
*
* @param pStack 指向待检测的栈的指针
*
* @return 若栈为空, 则返回 TRUE, 否则返回 FALSE
*/
int IsEmpty( ArrStack *pStack )
{
return pStack->height == ? TRUE : FALSE;
} /**
* @brief 将元素 pt 压入栈 pStack
*
* @param pStack 指向待压入元素的栈的指针
* @param pt 指向待压入元素的指针
*
* @return 返回成功压入后栈的高度
*/
int Push( ArrStack *pStack, ElemType *pt )
{
///检测是否需要扩容
if( pStack->height == pStack->size )
{ //需要扩容 //重新申请于原栈大小2倍大小的栈空间
ElemType *pe = (ElemType *)calloc( pStack->size * , sizeof(ElemType) ); //将旧栈内容拷贝到新栈内容
memcpy( pe, pStack->btm, pStack->size * sizeof(ElemType) ); //重置栈总容量大小
pStack->size = pStack->size * ; //释放旧栈空间
free( pStack->btm ); //将栈底指向新开辟的栈空间
pStack->btm = pe; //栈顶指向新栈最后一个元素
pStack->top = &pe[pStack->height-];
} //将新元素压入栈
pStack->btm[pStack->height].x = pt->x;
pStack->btm[pStack->height].y = pt->y; //栈高度自增一
++pStack->height; //栈顶指向最新栈元素
pStack->top = &pStack->btm[pStack->height-]; return pStack->height;
} /**
* @brief 将栈顶元素出栈 到 pt
*
* @param pStack 指向待弹出元素的栈的指针
* @param pt 指向接收弹出的元素的指针
*
* @return 出栈成功则返回出栈后栈的高度, 否则返回 -1
*/
int Pop( ArrStack *pStack, ElemType *pt )
{
///是否为空栈
if( pStack->height == )
return -; //将栈顶元素赋值到 pt
pt->x = pStack->top->x;
pt->y = pStack->top->y; //栈高度减一
--pStack->height; //栈顶指向栈顶元素的上一个元素
pStack->top = &pStack->btm[pStack->height-]; return pStack->height;
} /**
* @brief 获取栈顶元素到 pt
*
* @param pStack 指向待弹出元素的栈的指针
* @param pt 指向接收弹出的元素的指针
*
* @return 获取成功则返回栈顶元素的位置, 否则返回 -1
*
* @note 元素位置由 0 计起
*/
int GetTop( ArrStack *pStack, ElemType *pt )
{
pt->x = pStack->top->x;
pt->y = pStack->top->y; return pStack->height - ;
} /**
* @brief 从栈底到栈顶的每个元素依次执行 func 函数
*
* @param pStack 指向待处理的栈的指针
* @param func 需要执行的函数的指针
*
* @return void
*/
void ForEachStack( ArrStack *pStack, void (*func)(ElemType *pt) )
{
int i = ;
for( i = ; i < pStack->height; ++i )
{
func( &pStack->btm[i] );
}
} /**
* @brief 从栈顶到栈底的每个元素依次执行 func 函数
*
* @param pStack 指向待处理的栈的指针
* @param func 需要执行的函数的指针
*
* @return void
*/
void ReForEachStack( ArrStack *pStack, void (*func)(ElemType *pt) )
{
int i = pStack->height - ;
for( i; i >= ; --i )
{
func( &pStack->btm[i] );
}
} //测试 void display( ElemType *pt )
{
printf( "(%d,%d) ", pt->x, pt->y );
} int main()
{
///测试创建初始大小为 5 的栈
ArrStack *psk = CreateStack( ); ///测试 IsEmpty、GetSize、GetHeight
if( IsEmpty(psk) == TRUE )
printf( "Stack Size=%d, Stack Height=%d\n", GetSize(psk), GetHeight(psk) ); ElemType pt; int i = ;
///测试Push, 向栈内压入8个元素
printf( "\n向栈内压入8个元素后:\n" );
for( i = ; i < ; ++i )
{
pt.x = pt.y = i;
Push( psk, &pt );
}
//输出压入8个元素后的栈状态
printf( "Is empty = %d\n", IsEmpty(psk) );
printf( "Stack size = %d\n", GetSize(psk) );
printf( "Stack height = %d\n", GetHeight(psk) ); ///测试 ForEachStack、ReForEachStack
printf( "\n测试 ForEachStack、ReForEachStack:\n" );
ForEachStack( psk, display );
putchar('\n');
ReForEachStack( psk, display );
putchar('\n'); ///测试getTop
GetTop( psk, &pt );
printf( "\n栈顶元素为: (%d,%d)\n", pt.x, pt.y ); ///测试 Pop
Pop( psk, &pt );
printf( "\nPop弹出的元素为(%d,%d), 弹出后栈高:%d\n", pt.x, pt.y, GetHeight(psk) );
Pop( psk, &pt );
printf( "\nPop弹出的元素为(%d,%d), 弹出后栈高:%d\n", pt.x, pt.y, GetHeight(psk) ); ///测试Push
pt.x = pt.y = ;
Push( psk, &pt );
printf( "\nPop压入的元素为(%d,%d), 压入后栈高:%d\n", pt.x, pt.y, GetHeight(psk) ); ///执行全面出栈操作
printf( "\n执行全面出栈:\n" );
int n = GetHeight(psk);
for( i = ; i < n; ++i )
{
Pop( psk, &pt );
printf( "Pop弹出的元素为(%d,%d), 弹出后栈高:%d\n", pt.x, pt.y, GetHeight(psk) );
} ///销毁栈
DestroyStack( psk ); return ;
}

测试结果:

若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢。                                                                                                                                                                                                                                                                                                                                                       

C语言 栈 顺序结构 实现的更多相关文章

  1. C语言 串 顺序结构 实现

    一个能够自动扩容的顺序结构的串 ArrString (GCC编译). /** * @brief C语言 串 顺序结构 实现 * @author wid * @date 2013-11-01 * * @ ...

  2. C语言 队列 顺序结构 实现

    一个能够自动扩容的顺序结构的队列 ArrQueue (GCC编译). /** * @brief C语言顺序结构队列的实现 * @author wid * @date 2013-10-30 * * @n ...

  3. C语言之顺序结构

    该章内容:这章我们学习三大结构之一:顺序结构,它是程序从上往下顺序执行,是程序运行最简单的方式.printf和scanf函数使用和特例是必考知识.本章是考试的重点章节. 学习方法:从简单的顺序结构题目 ...

  4. (七)C语言之顺序结构

  5. Java 流程控制语句 之 顺序结构

    在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说,程序的流程对运行结果 有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过控制语句的执行顺序来实 ...

  6. C语言实现顺序栈以及栈的特点

    什么是栈? 同顺序表和链表一样,栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构,如下图所示. 从上图我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘于栈对数据 ...

  7. C语言 栈 链式结构 实现

    一个C语言链式结构实现的栈 mStack (GCC编译). /** * @brief C语言实现的链式结构类型的栈 * @author wid * @date 2013-10-30 * * @note ...

  8. [置顶] 栈/入栈/出栈顺序(c语言)-linux

    说明: 1.栈底为高地址,栈顶为低地址. 2.入栈顺序:从右到左. 解释1:栈在内存中的结构 [注:0x00 到 0x04之间间隔4个地址] 入栈:指针先指向0x10,从高地址向低地址方向填数值,最终 ...

  9. C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)

    上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...

随机推荐

  1. JavaScript 基础(七) 箭头函数 generator Date JSON

    ES6 标准新增了一种新的函数: Arrow Function(箭头函数). x => x *x 上面的箭头相当于: function (x){ return x*x; } 箭头函数相当于匿名函 ...

  2. Android,配置Activity为启动Activity(AndroidManifest.xml,application,intent-filter,MAIN,LAUNCHER)

    备忘: 将Activity注册为启动Activity. 在AndroidManifest.xml中的<application>元素中加入以下<activity>子元素内容: & ...

  3. RSA加密前端JS加密,后端asp.net解密,报异常

    RSA加密前端JS加密,后端asp.net解密,报异常 参考引用:http://www.ohdave.com/rsa/的JS加密库 前端JS加密代码: function GetChangeStr() ...

  4. asp.net项目下的web service返回json数据问题

    App_Code目录下放置WebService.cs文件,文件内容如: using System; using System.Collections.Generic; using System.Dat ...

  5. if条件里比较浮点数

    晚上看会儿书,基础的东西,很多都不熟练,不得不佩服那些人真的很厉害,为啥会想到那些,我这傻脑袋是想不到,暂时...... 比较3.3333与3 #!/bin/bash var1=`echo " ...

  6. 《CSS3秘籍》(第三版)-读书笔记(2)

    第6章 文本格式化 1.  使用字体 字体font-family: 通用的字体样式: serif字体最适用于冗长的文字信息.这种字体使字母主笔画的结尾处会有一些细小的“足”. sans-serif字体 ...

  7. 关于C# 窗体自动隐藏和加载的问题

    最近在写一个小项目,开发一个小程序配合其他软件使用,其中一款软件在使用工作时需要截图生成报告,此时不能有其他应用程式界面在显示器桌面显示,故需要自动隐藏和加载窗体,通过阅读Windows API实现了 ...

  8. 亿级Web系统的高容错性实践

    亿级Web系统的高容错性实践 背景介绍 大概三年前,我在腾讯负责的活动运营系统,因为业务流量规模的数倍增长,系统出现了各种各样的异常,当时,作为开发的我,7*24小时地没日没夜处理告警,周末和凌晨也经 ...

  9. 对比poj3050

    #include <stdio.h> const int MAXN = 10; const int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, ...

  10. shell 脚本注意事项

    设脚本名为test.sh 第一行应该为#! /bin/bash 1.运行和调试的结果是不一样的 调试 sh -x test.sh  这时在计算两个数的和sum=$[$a+$b]时得到sum=3+4,而 ...