zoukankan      html  css  js  c++  java
  • 数据结构与算法2 — 栈

    尊重作者劳动成果,转载请注明出处,谢谢!

    1. stack.h

    #ifndef stack_H
    #define stack_H
    
    #include <stddef.h>
    #include <sys/types.h>
    
    //栈,内部结构为数组,提供后进先出的数据访问方式,支持多种数据类型,包括:int、struct等
    typedef struct
    {
        void *data;      //数组
        size_t dataSize; //元素大小(字节)
        ssize_t top;     //栈顶,-1表示栈为空
        size_t capacity; //栈容量
    } Stack;
    
    //定义该宏可以直观的看出栈元素的数据类型,比如:Stack(int)
    #define Stack(type) Stack
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
        int stack_init(Stack *stack, size_t dataSize, size_t capacity);
        void stack_free(Stack *stack);
        void stack_clear(Stack *stack);
        int stack_expand(Stack *stack, size_t increment);
        int stack_shrink(Stack *stack);
        size_t stack_length(const Stack *stack);
        int stack_full(const Stack *stack);
        int stack_empty(const Stack *stack);
        int stack_push(Stack *stack, const void *data);
        int stack_pop(Stack *stack, void *data);
        void *stack_top(const Stack *stack);
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    2. stack.c

    #include "stack.h"
    #include <string.h>
    #include <stdlib.h>
    
    //初始化
    int stack_init(Stack *stack, size_t dataSize, size_t capacity)
    {
        if (stack == NULL || dataSize <= 0 || capacity <= 0)
            return -1;
    
        stack->data = malloc(capacity * dataSize);
        if (stack->data == NULL)
            return -1;
    
        memset(stack->data, 0, capacity * dataSize);
        stack->top = -1;
        stack->capacity = capacity;
        stack->dataSize = dataSize;
        return 0;
    }
    
    //释放内存
    void stack_free(Stack *stack)
    {
        if (stack == NULL)
            return;
    
        if (stack->data != NULL)
        {
            free(stack->data);
            stack->data = NULL;
        }
    
        stack->top = -1;
        stack->capacity = 0;
        stack->dataSize = 0;
    }
    
    //清空栈
    void stack_clear(Stack *stack)
    {
        if (stack == NULL)
            return;
    
        if (stack->data != NULL)
            memset(stack->data, 0, stack->capacity * stack->dataSize);
    
        stack->top = -1;
    }
    
    //扩充栈
    int stack_expand(Stack *stack, size_t increment)
    {
        if (stack == NULL || increment <= 0)
            return -1;
    
        void *data = realloc(stack->data, (increment + stack->capacity) * stack->dataSize);
        if (data == NULL)
            return -1;
    
        stack->data = data;
        stack->capacity += increment;
        return 0;
    }
    
    //收缩栈
    int stack_shrink(Stack *stack)
    {
        if (stack == NULL)
            return -1;
    
        if (stack_full(stack))
            return -1;
    
        size_t capacity;
        if (stack_empty(stack))
            capacity = 1; //栈为空,将容量缩减为1
        else
            capacity = stack->top + 1; //将容量缩减为top+1
    
        void *data = realloc(stack->data, capacity * stack->dataSize);
        if (data == NULL)
            return -1;
    
        stack->data = data;
        stack->capacity = capacity;
        return 0;
    }
    
    //获取栈长度
    size_t stack_length(const Stack *stack)
    {
        if (stack == NULL || stack->data == NULL)
            return 0;
    
        return stack->top + 1;
    }
    
    //判断栈是否已满
    int stack_full(const Stack *stack)
    {
        if (stack == NULL)
            return -1;
    
        if (stack->top < 0)
            return -1;
    
        return (size_t)stack->top == stack->capacity - 1;
    }
    
    //判断栈是否为空
    int stack_empty(const Stack *stack)
    {
        if (stack == NULL)
            return 1;
    
        return stack->top == -1;
    }
    
    //入栈
    int stack_push(Stack *stack, const void *data)
    {
        if (stack == NULL)
            return -1;
    
        if (stack_full(stack)) //栈满
            return -1;
    
        stack->top++;
        memcpy((char *)stack->data + stack->top * stack->dataSize, data, stack->dataSize);
        return 0;
    }
    
    //出栈
    int stack_pop(Stack *stack, void *data)
    {
        if (stack == NULL)
            return -1;
    
        if (stack_empty(stack)) //栈空
            return -1;
    
        if (data != NULL)
            memcpy(data, (char *)stack->data + stack->top * stack->dataSize, stack->dataSize);
    
        stack->top--;
        return 0;
    }
    
    //获取栈顶元素指针
    void *stack_top(const Stack *stack)
    {
        if (stack == NULL)
            return NULL;
    
        if (stack_empty(stack)) //栈空
            return NULL;
    
        return (char *)stack->data + stack->top * stack->dataSize;
    }
  • 相关阅读:
    DriveInfo 类 提供对有关驱动器的信息的访问
    遍历数组 例子
    怎么判断点击dataGridView1的是第几列
    无法加载协定为“ServiceReference1.LanguageService”的终结点配置部分,因为找到了该协定的多个终结点配置。请按名称指示首选的终结点配置部分。
    c#面试题及答案(一)
    SQL杂谈 ,有你想要的...
    TextView和Button的学习
    GitHub的学习和使用
    App的布局管理
    EditText制作简单的登录界面
  • 原文地址:https://www.cnblogs.com/chenyuxin/p/15214993.html
Copyright © 2011-2022 走看看