zoukankan      html  css  js  c++  java
  • C语言 栈 链式结构 实现

    一个C语言链式结构实现的栈 mStack (GCC编译)。

      1 /**
      2 * @brief C语言实现的链式结构类型的栈
      3 * @author wid
      4 * @date 2013-10-30
      5 *
      6 * @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!
      7 */
      8 
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 
     12 #define TRUE 1
     13 #define FALSE 0
     14 
     15 typedef struct SNODE
     16 {
     17     void *pelm;             //元素指针
     18     struct SNODE *next;     //指向下一栈节点
     19 }StackNode;
     20 
     21 typedef struct
     22 {
     23     StackNode *btm;      //栈底指针
     24     StackNode *top;      //指向栈顶元素
     25     int height;          //栈高度
     26 }mStack;
     27 
     28 //栈方法声明
     29 
     30 mStack *CreateStack();     //创建一个空的栈
     31 void DestroyStack( mStack *pStack );        //销毁栈
     32 void ClearStack( mStack *pStack );          //清空栈内元素
     33 int GetHeight( mStack *pStack );            //获取栈高度
     34 int IsEmpty( mStack *pStack );              //检测是否为空栈
     35 int Push( mStack *pStack, void *pdata );    //向栈内压入元素
     36 int Pop( mStack *pStack, void **pdata );    //将栈顶元素出栈
     37 int GetTop( mStack *pStack, void **pdata ); //获取栈顶元素
     38 void ForEachStack( mStack *pStack, void (*func)(void *pdata) );      //从栈顶到栈底的每个元素依次执行 func 函数
     39 
     40 
     41 //栈方法实现
     42 
     43 /**
     44 * @brief 创建一个高度为 nHeight 的栈
     45 *
     46 * @return 返回指向新建的栈的指针
     47 */
     48 mStack *CreateStack()
     49 {
     50     ///创建一个栈
     51     mStack *pStack = (mStack *)malloc( sizeof(mStack) );
     52 
     53     ///令栈顶指向栈底指向NULL
     54     pStack->top = pStack->btm = NULL;
     55 
     56     ///初始栈高度为0
     57     pStack->height = 0;
     58 }
     59 
     60 /**
     61 * @brief 销毁栈 pStack
     62 *
     63 * @param pStack 指向待销毁的栈的指针
     64 *
     65 * @return void
     66 */
     67 void DestroyStack( mStack *pStack )
     68 {
     69     StackNode *tmp = NULL;
     70 
     71     ///释放栈内节点
     72     while( tmp != NULL )
     73     {
     74         tmp = pStack->top->next;
     75         free( pStack->top );
     76         pStack->top = tmp;
     77     }
     78 
     79     ///释放栈
     80     free( pStack );
     81 }
     82 
     83 /**
     84 * @brief 清空栈内元素
     85 *
     86 * @param pStack 指向待清空元素的栈的指针
     87 *
     88 * @return void
     89 */
     90 void ClearStack( mStack *pStack )
     91 {
     92     StackNode *tmp = NULL;
     93     while( tmp != NULL )
     94     {
     95         tmp = pStack->top->next;
     96         free( pStack->top );
     97         pStack->top = tmp;
     98     }
     99 
    100     pStack->top = pStack->btm = NULL;
    101 
    102     pStack->height = 0;
    103 }
    104 
    105 /**
    106 * @brief 获取栈当前高度
    107 *
    108 * @param 指向待获取高度的栈的指针
    109 *
    110 * @return 返回栈当前高度
    111 */
    112 int GetHeight( mStack *pStack )
    113 {
    114     return pStack->height;
    115 }
    116 
    117 /**
    118 * @brief 检测是否为空栈
    119 *
    120 * @param pStack 指向待检测的栈的指针
    121 *
    122 * @return 若为空, 则返回 TRUE, 否则返回 FALSE
    123 */
    124 int IsEmpty( mStack *pStack )
    125 {
    126     return pStack->height == 0 ? TRUE : FALSE;
    127 }
    128 
    129 /**
    130 * @brief 向栈内压入元素
    131 *
    132 * @param pStack 待压入元素的栈
    133 * @param pdata 指向待压入栈元素的指针
    134 *
    135 * @return 返回成功入栈后栈的高度
    136 */
    137 int Push( mStack *pStack, void *pdata )
    138 {
    139     ///创建一个栈节点
    140     StackNode *pNode = (StackNode *)malloc( sizeof(StackNode) );
    141 
    142     ///为该节点赋值
    143     pNode->pelm = pdata;
    144     pNode->next = pStack->top;
    145 
    146     ///令栈顶指向最新节点
    147     pStack->top = pNode;
    148 
    149     ++pStack->height;
    150 }
    151 
    152 /**
    153 * @brief 将栈顶元素出栈
    154 *
    155 * @param pStack 指向待执行出栈操作的栈的指针
    156 * @param pdata 接收弹出的元素的指针
    157 *
    158 * @return 出栈成功则返回出栈后栈的高度, 否则返回 -1
    159 */
    160 int Pop( mStack *pStack, void **pdata )
    161 {
    162     ///检测是否为空栈
    163     if( pStack->top == pStack->btm  )
    164         return -1;
    165 
    166     ///取得栈节点数据元素值
    167     *pdata = pStack->top->pelm;
    168 
    169     ///将栈顶指针向下退一位
    170     StackNode *p = pStack->top->next;
    171     free( pStack->top );
    172     pStack->top = p;
    173 
    174     return --pStack->height;
    175 }
    176 
    177 /**
    178 * @brief 获取栈顶元素到 pt
    179 *
    180 * @param pStack 指向待弹出元素的栈的指针
    181 * @param pdata 指向接收弹出的元素的指针
    182 *
    183 * @return 获取成功则返回栈顶元素的位置, 否则返回 -1
    184 *
    185 * @note 元素位置由 0 计起
    186 */
    187 int GetTop( mStack *pStack, void **pdata )
    188 {
    189     ///检测是否为空栈
    190     if( pStack->height == 0 )
    191         return -1;
    192 
    193     *pdata = pStack->top->pelm;
    194 
    195     return pStack->height - 1;
    196 }
    197 
    198 /**
    199 * @brief 从栈底到栈顶的每个元素依次执行 func 函数
    200 *
    201 * @param pStack 指向待处理的栈的指针
    202 * @param func 需要执行的函数的指针
    203 *
    204 * @return void
    205 */
    206 void ForEachStack( mStack *pStack, void (*func)(void *pt) )
    207 {
    208     StackNode *tmp = pStack->top;
    209     while( tmp != NULL )
    210     {
    211         func( tmp->pelm );
    212         tmp = tmp->next;
    213     }
    214 }
    215 
    216 void display( void *pn )
    217 {
    218     printf( "%d ", *(int *)pn );
    219 }
    220 
    221 int main()
    222 {
    223     int a = 10, b = 20, c = 30, n = 0;
    224     void *pa = NULL;
    225 
    226     ///测试 CreateStack
    227     mStack *psk = CreateStack();
    228 
    229     ///测试 IsEmpty、GetHeight
    230     if( IsEmpty(psk) == TRUE )
    231         printf( "Init Height = %d
    ", GetHeight(psk) );
    232 
    233     ///测试 Push
    234     printf("压入数字 10
    "); Push( psk, &a );
    235     printf("压入数字 20
    "); Push( psk, &b );
    236     printf( "压入2元素后栈高度 = %d
    ", GetHeight(psk) );
    237 
    238     ///测试 Pop
    239     printf( "
    测试 Pop:
    " );
    240     n = Pop( psk, &pa );
    241     if( n != -1 )
    242         printf( "Pop = %d
    ", *(int *)pa );
    243 
    244     n = Pop( psk, &pa );
    245     if( n != -1 )
    246         printf( "Pop = %d
    ", *(int *)pa );
    247 
    248     n = Pop( psk, &pa );
    249     if( n != -1 )
    250         printf( "Pop = %d
    ", *(int *)pa );
    251 
    252     ///测试清空栈
    253     Push( psk, &a );
    254     printf("
    清空栈..");
    255     ClearStack( psk );
    256     printf( "
    清空后栈高度 = %d
    ", GetHeight(psk) );
    257 
    258     ///测试 ForEachStack
    259     printf("
    压入3元素..");
    260     Push( psk, &a );
    261     Push( psk, &b );
    262     Push( psk, &c );
    263     printf("
    测试 ForEachStack: "); ForEachStack( psk, display );
    264 
    265     ///测试GetTop
    266     printf("
    测试GetTop:
    ");
    267     n = GetTop( psk, &pa );
    268     if( n != -1 )
    269         printf( "GetTop = %d
    ", *(int *)pa );
    270 
    271     ///再次输出当前栈高度
    272     printf( "
    当前栈高度Height = %d
    ", GetHeight(psk) );
    273 
    274     ///测试 DestroyStack
    275     printf("
    销毁栈..
    ");
    276     DestroyStack( psk );
    277 
    278     return 0;
    279 }

    测试运行:

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

  • 相关阅读:
    18.中介者模式
    17.迭代器模式
    16.解释器模式
    15.命令模式
    Git超详细用法,通俗易懂
    CSS Sprites精灵图(雪碧图)
    小程序被冻结,忘记原始ID,如何找回?
    vue组件-视频播放之video.js
    基础设计模式-04 复杂对象创建的建造器模式
    基础设计模式-03 从过滤器(Filter)校验链学习职责链模式
  • 原文地址:https://www.cnblogs.com/mr-wid/p/3396339.html
Copyright © 2011-2022 走看看