ds通用stack(1.3)

现在我们来讲这个通用STACK的具体实现, 在头文件里面我们只是声明了struct _ds_stk, 由于接口里面使用到的都是其指针类型而将其具体定义实现了隐藏。

其具体的结构定义如下所示:

struct _ds_stk {

        size_t _top;              /** top of the stack    */

        struct node {

                void* value;      /** stack value         */

                struct node* next;/** next stack value    */

        }* _head;

        ds_alloc_func _allocF;    /** allocate function   */

        ds_free_func  _freeF;     /** deallocate function */

        ds_copy_func  _copyF;     /** copy data function  */

};

在这个结构里面我们可以看到使用了一个 struct node的链表来存储到栈里面的具体数据信息, _top用于记录该栈里面存储的元素个数, 同时还有需要使用到的相应元素操作的函数。

先实现默认的元素操作函数(为了防止客户程序员忘记实现自己对于的操作函数, 内部默认的元素操作接口, 都只是对指针的单纯记录, 并不对具体元素的信息进行拷贝……)

static void* _defAlloc(void* v) { return v; }

static void _defFree(void* v) {}

static int _defCopy(void* dest, void* src) {

        dest = src; return 1;

}

接下来, 便是该通用STACK的各个相关操作接口的具体实现了, 为了实现栈的(FILO), 我们对该链表的元素插入操作实行了头插法, 这样出栈就可以是直接释放掉链表头结点的元素数据信息了, 这样便实现了栈的先进后出。其具体实现如下所示:

struct _ds_stk* 

ds_stk_new(ds_alloc_func allocF, ds_free_func freeF, ds_copy_func copyF) {

        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);

        stk->_allocF = NULL != allocF ? allocF : _defAlloc;

        stk->_freeF  = NULL != freeF ? freeF : _defFree;

        stk->_copyF  = NULL != copyF ? copyF : _defCopy;

        

        return stk;

}

void 

ds_stk_free(struct _ds_stk** stk) {

        struct node* i = NULL;

        struct node* u = NULL;

        if (NULL == *stk) return;

        for (i = (*stk)->_head; NULL != i; i = u) {

                u = i->next;

                (*stk)->_freeF(i->value);

                free(i);

        }

        free(*stk);

        *stk = NULL;

}

size_t 

ds_stk_size(struct _ds_stk* stk) {

        return (NULL != stk ? stk->_top : 0L);

}

int 

ds_stk_empty(struct _ds_stk* stk) {

        return (NULL != stk ? 0L == stk->_top : 0);

}

int 

ds_stk_push(struct _ds_stk* stk, void* v) {

        struct node* e = NULL;

        size_t sz = sizeof(struct node);

        

        if (NULL == stk) return 0;

        e = (struct node*)malloc(sz);

        if (NULL == stk) return 0;

        memset(e, 0, sz);

        e->value   = stk->_allocF(v);

        e->next    = stk->_head;

        stk->_head = e;

        stk->_top++;

        return 1;

}

int 

ds_stk_pop(struct _ds_stk* stk, void* v) {

        struct node* e = NULL;

        

        if (NULL == stk || NULL == v || stk->_top <= 0

                return 0;

        e = stk->_head;

        stk->_head = e->next;

        stk->_top--;

        stk->_copyF(v, e->value);

        stk->_freeF(e->value);

        free(e);

        e = NULL;

        return 1;

}

现在看了通用栈的具体实现觉得很简单是吧? 嘿嘿, 其实这样也是一种设计的原则, 很多东西我们自己是不知道的, 但是客户知道, 那我们就让客户去实现不就成了, 这样我们就只需要向客户提供实现的原则方法便OK了。

    好了今天就到此为止吧, 其实明白了这个通用STACK的实现, 实现别的通用数据结构就很简单了。(如有不合理的地方希望大家多多指出, 若有更优秀的见解希望高人不吝赐教, 谢谢!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值