歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

用C語言實現簡單的棧

棧是一種常見的數據結構,主要特點是“後進先出”。以下是用C語言實現的簡單的棧。

頭文件 stack.h ,定義棧的結構體和相關的操作:

#ifndef STACK_H
#define STACK_H
 
enum { STACK_OK = 0, STACK_OVERFLOW, STACK_ERROR, };
 
typedef int ElemType;
 
struct stack {
    ElemType *data;
    ElemType *top;
    int capability;
};
 
 
void stack_init(struct stack *st, int capability);
void stack_destroy(struct stack *st);
int stack_push(struct stack *st, ElemType elem);
int stack_pop(struct stack *st);
ElemType stack_top(const struct stack *st);
int stack_size(const struct stack *st);
int stack_capability(const struct stack *st);
int stack_full(const struct stack *st);
int stack_empty(const struct stack *st);
void stack_clear(struct stack *st);
 
#endif

C文件 stack.c,實現stack的相關操作。

#include "stack.h"
#include <assert.h>
#include <stdlib.h>
 
void stack_init(struct stack *st, int capability)
{
    assert(st && capability > 0);
    st->data = (ElemType *)malloc(sizeof(ElemType) * capability);
    assert(st->data);
    st->top = st->data;
    st->capability = capability;
}
 
void stack_destroy(struct stack *st)
{
    assert(st);
    if (st->data)
        free(st->data);
    st->data = 0;
    st->top = 0;
    st->capability = 0;
}
 
int stack_push(struct stack *st, ElemType elem)
{
    assert(st);
    if (stack_full(st))
        return STACK_OVERFLOW;
    *(st->top++) = elem;
    return STACK_OK;
}
 
int stack_pop(struct stack *st)
{
    assert(st);
    if (stack_empty(st))
        return STACK_OVERFLOW;
    st->top--;
    return STACK_OK;
}
 
ElemType stack_top(const struct stack *st)
{
    assert(st);
    if (stack_empty(st))
        return (ElemType)0;
    else
        return *(st->top - 1);
}
 
int stack_size(const struct stack *st)
{
    assert(st);
    return (st->top - st->data);
}
 
int stack_capability(const struct stack *st)
{
    assert(st);
    return st->capability;
}
 
int stack_full(const struct stack *st)
{
    return (stack_size(st) == stack_capability(st));
}
 
int stack_empty(const struct stack *st)
{
    return (stack_size(st) == 0);
}
 
void stack_clear(struct stack *st)
{
    assert(st);
    st->top = st->data;
}

上面在stack.h 中定義了ElemType為int,是簡單的數據類型。上面的實現也是針對簡單數據庫類型的,對於一些稍復雜的數據類型,上面的實現不適用。例如,如果棧元素需要用某個函數來銷毀,則stack_clear就不適用了。

實現中也用到了assert,不過我不大喜歡用assert,因為會使程序中止。其實可以用if來作檢測而不中止,或是不作檢測,靠使用者自行判斷。

上面實現也沒有用到 STACK_ERROR 這個值。

下面是提供測試的main.c

#include <stdio.h>
#include "stack.h"
 
int main()
{
    struct stack st;
    int i;
    stack_init(&st, 5);
 
    printf("-------------- init stack ----------------\n");
    printf("stack capability: %d\n", stack_capability(&st));
    printf("stack size: %d\n", stack_size(&st));
    printf("stack empty ? %s\n", stack_empty(&st) ? "Y" : "N");
    printf("stack full ? %s\n", stack_full(&st) ? "Y" : "N");
 
    printf("-------------- pushing elements ----------------\n");
    for (i = 0; i < 10; ++i) {
        printf("push %i OK ? %s\n", i,
            (stack_push(&st, i) == STACK_OK ? "Y" : "N"));
        printf("stack size: %d\n", stack_size(&st));
        printf("stack empty ? %s\n", stack_empty(&st) ? "Y" : "N");
        printf("stack full ? %s\n", stack_full(&st) ? "Y" : "N");
    }
 
    printf("-------------- poping elements ----------------\n");
    while (!stack_empty(&st)) {
        printf("top: %d\n", stack_top(&st));
        printf("pop OK? %s\n", stack_pop(&st) == STACK_OK ? "Y" : "N");
        printf("stack size: %d\n", stack_size(&st));
        printf("stack empty ? %s\n", stack_empty(&st) ? "Y" : "N");
        printf("stack full ? %s\n", stack_full(&st) ? "Y" : "N");
    }
 
    printf("-------------- clear stack ----------------\n");
    stack_clear(&st);
    printf("stack capability: %d\n", stack_capability(&st));
    printf("stack size: %d\n", stack_size(&st));
    printf("stack empty ? %s\n", stack_empty(&st) ? "Y" : "N");
    printf("stack full ? %s\n", stack_full(&st) ? "Y" : "N");
 
    printf("-------------- destroy stack --------------\n");
    stack_destroy(&st);
 
    return 0;
}

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

Copyright © Linux教程網 All Rights Reserved