ds通用stack(1.0)

本文介绍了一种使用C语言宏定义实现通用栈的方法,并详细展示了栈的基本操作如创建、销毁、压栈、弹栈等。此外,作者还讨论了这种方法的优点和局限性。

 

 

    此文转自我的另一个博客(http://hi.baidu.com/zfeagles)

    很久都没有来这里写什么东西了, 想想由于工作的繁忙(或许这个只是我自己懒惰的借口吧, 哈哈哈哈)差不多一年都没有好好写些文字了。

    希望这次的想法可以好好的认真完成吧, 个人打算好好的把数据结构再实现一遍, 准备实现一套纯C的通用数据结构, 虽然网上有很多其他高人的开源东东, 但还是决定自己写一个, 就当是自己的学习、理解吧。当然我也知道我的功力尚且很浅, 有什么地方不合理的还请路过的高人不要见笑, 不吝赐教! 谢谢!

    C语言里面没有向C++里面的template,实现通用的stack相对来说还是有点难度的, 但是C语言既然是最简单灵活的语言, 当然也是有其实现的方式的。这里我先给出一种个人觉得最简单偷懒的实现方法, 那就是全部使用C语言宏来实现。好了不说废话了, 先贴出代码吧(这里为了篇幅省了注释)。

#ifndef __DS_STACK_H__
#define __DS_STACK_H__

#ifdef  __cplusplus
extern "C" {
#endif  /* __cplusplus */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define __DS_STACK_DEC(_Type)/
typedef void (*_ds_elem_func)(_Type);/
struct _DS_STK {/
        size_t _top;/
        struct node {/
                _Type value;/
                struct node* next;/
        }* _h;/
};/
/
/
extern struct _DS_STK* _ds_stk_new(void) {/
        struct _DS_STK* stk = NULL;/
        size_t _sz = sizeof(struct _DS_STK);/
/
        stk = (struct _DS_STK*)malloc(_sz);/
        if (NULL == stk) return NULL;/
        memset(stk, 0, _sz);/
        return stk;/
}/
/
/
extern void _ds_stk_free(struct _DS_STK** stk) {/
        struct node* i = NULL;/
        struct node* u = NULL;/
/
        if (NULL == *stk) return;/
        for (i = (*stk)->_h; NULL != i; i = u) {/
                u = i->next;/
                free(i);/
        }/
        free(*stk);/
        *stk = NULL;/
}/
/
/
extern size_t _ds_stk_size(struct _DS_STK* stk) {/
        return (NULL != stk ? stk->_top : 0L);/
}/
/
/
extern int _ds_stk_empty(struct _DS_STK* stk) {/
        return (NULL != stk ? 0L == stk->_top : 0);/
}/
/
/
extern int _ds_stk_push(struct _DS_STK* stk, _Type v) {/
        struct node* e = NULL;/
        size_t len = sizeof(struct node);/
/
        if (NULL == stk) return 0;/
        e = (struct node*)malloc(len);/
        if (NULL == e) return 0;/
        memset(e, 0, len);/
        e->value = v;/
        e->next  = stk->_h;/
        stk->_h  = e;/
        stk->_top++;/
        return 1;/
}/
/
/
extern _Type _ds_stk_pop(struct _DS_STK* stk) {/
        struct node* e = NULL;/
        _Type  v;/
/
        memset(&v, 0, sizeof(_Type));/
        if (NULL == stk || stk->_top <= 0) return v;/
        e = stk->_h;/
        stk->_h = e->next;/
        stk->_top--;/
        v = e->value;/
        free(e);/
        e = NULL;/
        return v;/
}/
/
extern int _ds_stk_oper(struct _DS_STK* stk, _ds_elem_func operF) {/
        struct node* e = NULL;/
/
        if (NULL == stk) return 0;/
        e = stk->_h;/
        while (NULL != e) {/
                if (NULL != operF) operF(e->value);/
                e = e->next;/
        }/
        return 1;/
}

 


#ifdef  __cplusplus
}
#endif  /* __cplusplus */

#endif  /* __DS_STACK_H__ */

    是不是觉得这样做有点投机取巧的感觉呢? 确实是这样的, 但是我们所需要的功能却是实现了。使用宏定义的好处是可以很方便的实现通用类型的stack, 但是其缺点也很明显每使用一种类型的stack的时候都必须重新调用__DS_STACK_DEC宏, 同时在定义了一种类型的stack之后, stack的元素类型也就唯一确定了, 不能实现在stack中存放任意类型的数据, 这一点倒是有点像STL(你觉得呢???)。同时暴露了所有接口的实现, 给客户程序员使用的时候造成了混乱。

    下一次, 我们再讨论通用stack的其他实现方法吧。(自我感觉, 这个真的很像STL的方式 。。。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值