数据结构栈stack的动态数组实现

stack:是一种的后进先出的线性数据结构,其操作一端是受限的,即只能从栈顶操作。

通常,其实实现可以有动态数组实现,也可以由链表实现,似乎链表实现更合理。

同过数组实现的栈的一个好处,可以是栈想数组那样随机的访问stack中的元素,而且通过预留量不用频繁的内存分配操作。


本文,针对stack 实现一种用C语言实现的动态数组栈。栈的容积可以随栈中元素的个数,将其容量自动增减,本文实现的调节因子是2.


实现代码如下:

1.实现的接口文件:stack.h

#ifndef STACK_H
#define STACK_H

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

/* initial stack capacity in terms of elements */
#define	STACK_INITIAL_SIZE	1       // 1 未测试使用,其值可以根据具体的需求定。

#define CHECK_MEM(p) \
if ((p) == NULL) { \
    fprintf(stderr, "out of memory: in file %s, line %d, function %s.\n", __FILE__, __LINE__, __FUCTION__); \
    exit(1); \
}

typedef struct stack_t {
    void    *base;
    void    *top;
    int	    element_size;	        /* element size */
    unsigned int	    capacity;	/* stack capacity in byte */
} stack;



/* stack operations */
void  stack_init(stack *stack, int element_size);
void  stack_free(stack *stack);

int   stack_empty(stack *stack);
int   stack_size(stack *stack);
void  stack_push(stack *stack, void *element);
void* stack_pop(stack *stack);

/* clear elements to make stack empty, but don't free memory */
void stack_clear(stack *stack);

/* copy contents of stack x to stack y; y must have been initiated and not freed */
void stack_copy(stack *x, stack *y);



#endif  /* STACK_H */

2. stack功能实现文件:stack.c

#include "stack.h"

/* stack operations */
void stack_init(stack *stack, int element_size) {

    stack->base = (void *) malloc(STACK_INITIAL_SIZE * element_size);
    if (stack->base == NULL) {
        fprintf(stderr, "out of memory (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__);
        exit(1);
    }

    stack->element_size = element_size;
    stack->capacity = STACK_INITIAL_SIZE * element_size;
    stack->top = stack->base;
}


void stack_free(stack *stack) {
    if (stack->base != NULL) {
        free(stack->base);
        stack->base = NULL;
    }

    stack->element_size = 0;
    stack->capacity = 0;
    stack->top = NULL;
}

int stack_empty(stack *stack) {
    assert(NULL != stack);
    assert(stack->top >= stack->base);

    return (stack->top == stack->base) ? 1 : 0;
}

int stack_size(stack *stack) {
    assert(NULL != stack);
    assert(stack->top >= stack->base);

    return (stack->top - stack->base) / stack->element_size;
}

void stack_push(stack *stack, void *element) {
    if(stack->top == (stack->base + stack->capacity)) {
        void *base;

        int n = stack->capacity;
        stack->capacity <<= 1;
        base = (void *) realloc(stack->base, stack->capacity);
        if (base == NULL) {
            fprintf(stderr, "out of memory (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__);
            stack_free(stack);
            exit(1);
        }
       // if(stack->base) printf("stack base: %p; base: %p\n", stack->base, base);
        stack->base = base;
        stack->top = base + n;
    }

    memcpy(stack->top, element, stack->element_size);
    stack->top += stack->element_size;
}

void* stack_pop(stack *stack) {
    if (stack_empty(stack)) {
        return NULL;
    }

    if((stack->top - stack->base) > STACK_INITIAL_SIZE && (stack->top - stack->base) < (stack->capacity >> 1)) {
       void *base;

        stack->capacity >>= 1;
        base = (void *) realloc(stack->base, stack->capacity);
        if (base == NULL) {
            fprintf(stderr, "memory relloca error:(in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__);
            stack_free(stack);
            exit(1);
        }
       // if(stack->base) printf("stack base: %p; base: %p\n", stack->base, base);
        stack->base = base;
        // printf("pop\n");
    }

    stack->top -= stack->element_size;

    return stack->top;

}

/* clear elements to make stack empty, but don't free memory */
void stack_clear(stack *stack) {
    stack->top = stack->base;
}



/* copy contents of stack x to stack y; y must have been initiated and not freed */
void stack_copy(stack *x, stack *y) {
    assert(NULL!=x && NULL!=y);

    /* first free stack y */
    stack_free(y);

    y->base = (void *) malloc(x->capacity);
    if (y->base == NULL) {
        fprintf(stderr, "out of memory (in file %s : line %d : fuction %s.)\n", __FILE__, __LINE__, __FUNCTION__);
        stack_free(x);
        exit(1);
    }

    int len = x->top - x->base;
    memcpy(y->base, x->base, len);
    y->element_size = x->element_size;
    y->capacity = x->capacity;
    y->top = y->base + len;
}




3.测试stack的文件:main.c

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

#include "stack.h"

void  printArray(int a[], int len);


int main(int argc, char* argv[])
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int len = sizeof(a) / sizeof(a[0]);
    int i;
    stack stack;


    printArray(a, len);

    stack_init(&stack, sizeof(a[0]));

    //printf("%d\n", stack_size(&stack));
    for(i = 0; i < len; ++i) {
        stack_push(&stack, &a[i]);
    }
    //printf("%d\n", stack_size(&stack));
    //printf("%d\n", stack.capacity);
    while(!stack_empty(&stack)) {
        printf("%d\t", *(int *)stack_pop(&stack));
    }
    printf("\n");
    //printf("%d\n", stack.capacity);
    //printf("%d\n", stack_size(&stack));

    stack_free(&stack);

    return 0;
}


void printArray(int a[], int len) {
    int i;

    for(i=0; i<len; i++) {
        printf("%d\t", a[i]);
    }

    printf("\n");
}

测试输出:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值