zoukankan      html  css  js  c++  java
  • 系统程序员成长计划组合的威力(三)

    转载时请注明出处和作者联系方式
    文章出处:http://www.limodev.cn/blog
    作者联系方式:李先静 <xianjimli at hotmail dot com>

    栈是一种后进先出(LIFO, last in first out)的数据结构,与队列的先进先出(FIFO)相比,这种规则似乎不太公平,计算机可不管这个。事实上,栈是最重要的数据结构之一:没有栈,基于下推 自动机的编译器不能工作,我们只能写汇编程序。没有栈,无法实现递归/多级函数调用,程序根本就无法工作。

    栈主要的接口函数有:

    o 创建栈 stack_create
    o 取栈顶元素 stack_top
    o 放入元素到栈顶stack_push
    o 删栈栈顶元素stack_pop
    o 取栈中元素个数 stack_length
    o 遍历栈中的元素stack_foreach
    o 销毁栈 stack_destroy

    栈同样是链表和数组的一种特殊形式而已,下面我们重用链表来实现栈:

    o 栈的数据结构

    struct _Stack
    {
    DList* dlist;
    };

    这里和队列的数据结构一样,由一个链表组成。

    o 创建栈

    Stack* stack_create(DataDestroyFunc data_destroy, void* ctx)
    {
    Stack* thiz = (Stack*)malloc(sizeof(Stack));

    if(thiz != NULL)
    {
    if((thiz->dlist = dlist_create(data_destroy, ctx)) == NULL)
    {
    free(thiz);
    thiz = NULL;
    }
    }

    return thiz;
    }

    创建栈时,除了分配自己的空间外,就是简单的创建一个双向链表。

    o 取栈顶元素

    Ret      stack_top(Stack* thiz, void** data)
    {
    return_val_if_fail(thiz != NULL && data != NULL, RET_INVALID_PARAMS);

    return dlist_get_by_index(thiz->dlist, 0, data);
    }

    我们认为链表的第一个元素是栈顶,取栈顶的元素就是取链表的第一个元素。

    o 放入元素到栈顶

    Ret      stack_push(Stack* thiz, void* data)
    {
    return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);

    return dlist_prepend(thiz->dlist, data);
    }

    放入元素到栈顶就是插入一个元素到链表头。

    o 删栈栈顶元素

    Ret      stack_pop(Stack* thiz)
    {
    return_val_if_fail(thiz != NULL, RET_INVALID_PARAMS);

    return dlist_delete(thiz->dlist, 0);
    }

    删栈栈顶元素就是删除链表的第一个元素。

    o 取栈中元素个数

    size_t   stack_length(Stack* thiz)
    {
    return_val_if_fail(thiz != NULL, 0);

    return dlist_length(thiz->dlist);
    }

    栈中的个数等同于链表的个数。

    o 遍历栈中的元素

    Ret      stack_foreach(Stack* thiz, DataVisitFunc visit, void* ctx)
    {
    return_val_if_fail(thiz != NULL && visit != NULL, RET_INVALID_PARAMS);

    return dlist_foreach(thiz->dlist, visit, ctx);
    }

    遍历栈中的元素等同于遍历链表中的元素。

    o 销毁栈

    void stack_destroy(Stack* thiz)
    {
    if(thiz != NULL)
    {
    dlist_destroy(thiz->dlist);
    thiz->dlist = NULL;

    free(thiz);
    }

    return;
    }

    销毁双向链表然后释放自身的空间。

    栈是一个非常重要的数据,但奇怪的是我们很少有机会去写它。事实上,我从来没有在工作中写过一个栈。这是怎么回事呢?原因是我们的计算机本身是基于 栈的,很多事情计算机已经在我们不知道的情况下帮我们处理了,比如函数调用(特殊是递归调用),计算机帮我们处理了。用递归下降进行的语法分析利用了函数 调用的递归性,也不需要显式的构造栈。

  • 相关阅读:
    题解 CF934A 【A Compatible Pair】 ——贪心
    洛谷 P3381 【【模板】最小费用最大流】
    洛谷 P3376 【【模板】网络最大流】
    洛谷 P1027 【Car的旅行路线】
    TYVJ P1039 【忠诚2】
    洛谷 P1273 【有线电视网】
    斯特林数相关
    从 简单容斥 到 min-max 容斥 与 二项式反演
    POI2011 Lightning Conductor
    LOJ6089 小 Y 的背包计数问题
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167554.html
Copyright © 2011-2022 走看看