数据结构 --- 顺序栈(C语言实现)

目录

一、栈基础知识

二、顺序栈数据结构

二、顺序栈增删改查函数声明

三、创建顺序栈

1、栈头部动态创建

2、栈头部静态创建

四、出栈

五、入栈

1、不支持动态扩容

2、支持替代扩容

六、栈删除

七、栈销毁

八、验证程序


一、栈基础知识

        在平时开发中,栈是一种非常常见的数据结构,例如函数调用、系统中断、表达式求值,相信每一个做开发的小伙伴,不管使用语言为何种,肯定都自己写过或用过这样的数据结构。栈就是一种“操作受限”的后进先出的线性表,只允许在一端插入和删除数据;所以栈的操作相对数据和链表就比较简单了,主要为入栈 和 出栈 操作,也就是在栈顶插入一个数据和在栈顶删除一个数据。

        那么如何实现一个栈呢?实际上,可以通过两种方式来实现,一种是用数组来实现的顺序栈,和使用链表来实现的链式栈。不管基于数组还是链表,入栈、出栈的时间复杂度都为 O(1)

  • A:为什么函数调用要用“栈”来保存临时变量呢?用其他数据结构不行吗?
  • Q:从调用函数进入被调用函数,对于数据来说,变化的是什么呢?是作用域。所以根本上,只要能保证每进入一个新的函数,都是一个新的作用域就可以。而要实现这个,用栈就非常方便。在进入被调用函数的时候,分配一段栈空间给这个函数的变量,在函数结束的时候,将栈顶复位,正好回到调用函数的作用域内。

二、顺序栈数据结构

#define ARRAY_STACK_SIZE(pstack)     (pstack->size)
#define ARRAY_STACK_IS_EMPTY(pstack) (pstack->pos == -1)
#define ARRAY_STACK_IS_FULL(pstack)  (pstack->pos == (pstack->size - 1))

struct array_stack
{
    int size; /* stack total size */
    int pos;  /* stack cur position rang:-1 -- (size-1)*/
    int tpsz; /* data type size */
    void *p; /* stack space */
};

二、顺序栈增删改查函数声明

extern struct array_stack* array_stack_creat(int size, int tpsz);
extern int array_stack_init   (struct array_stack *stack, int size, int tpsz);
extern int array_stack_empty  (struct array_stack *stack);
extern int array_stack_destory(struct array_stack *stack);
extern int array_stack_pop (struct array_stack *stack, void *out_data);
extern int array_stack_push(struct array_stack *stack, void *in_data);
extern int array_stack_push_dyn(struct array_stack *stack, void *in_data);

extern void array_stack_test(void);

三、创建顺序栈

1、栈头部动态创建

/**
 * dynamically creat and init an array stack.
 * 
 * @param size: array size
 * @param tpsz: data type size
 * @return result: array stack or NULL
 */
struct array_stack* array_stack_creat(int size, int tpsz)
{
    struct array_stack *stack = NULL;

    if (size <= 0 || tpsz <= 0)
        return NULL;

	/* malloc an array stack struct */
    stack = ARRAY_STACK_MALLOC(sizeof(*stack));
    if (stack == NULL)
        return NULL;
	
	/* calloc an array stack */
	void *p = ARRAY_STACK_CALLOC(1, (size * tpsz));
	if (p == NULL)
		return NULL;

    stack->size = size;
    stack->tpsz = tpsz;
    stack->pos = -1;
    stack->p = p;
    
    return stack;
}

2、栈头部静态创建

/**
 * init a static array stack.
 * 
 * @param stack: 
 * @param size: array size
 * @param tpsz: array data type length
 * @return -1:stack is null or malloc fail
 *          0:success
 */
int array_stack_init(struct array_stack *stack, int size, int tpsz)
{
	if (stack == NULL)
		return -1;
	
	/* calloc an array stack */
	void *p = ARRAY_STACK_CALLOC(1, (size * tpsz));
	if (p == NULL)
		return NULL;

    stack->size = size;
    stack->tpsz = tpsz;
    stack->pos = -1;
    stack->p = p;
	
	return 0;
}

四、出栈

/**
 * pop data from the array stack.
 * 
 * @param array_stack: array stack
 * @return -1: fail
 *         -2: stack is empty
 *          0: success
 */
int array_stack_pop(struct array_stack *stack, void *out_data)
{
    char *pbegin = NULL;
	void *data = NULL;

    if (stack == NULL)
        return -1;

	/* stack is empty */
    if(ARRAY_STACK_IS_EMPTY(stack))
        return -2;

	pbegin = stack->p;
    data = pbegin + stack->tpsz * stack->pos;
    memcpy(out_data, data, stack->tpsz);
    stack->pos--;

    return 0;
}

五、入栈

1、不支持动态扩容

/**
 * push data to the array stack.
 * 
 * @param array_stack: array stack
 * @return -1: fail
 *         -2: stack is full
 *          0: success
 */
int array_stack_push(struct array_stack *stack, void *in_data)
{
	char *pbegin = NULL;
    void *data = NULL;

    if (stack == NULL)
        return -1;

	/* stack is full */
	if(ARRAY_STACK_IS_FULL(stack))
        return -2;

	pbegin = stack->p;
    stack->pos++;
    data = pbegin + stack->tpsz * stack->pos;
    memcpy(data, in_data, stack->tpsz);

    return 0;
}

2、支持替代扩容

/**
 * Support dynamic expansion of sequential stack, 
 * when the stack is full to reapply for 2 times the size of the stack space.
 * 
 * @param array_stack: array stack
 * @return -1: fail
 *         -2: stack is full
 *          0: success
 */
int array_stack_push_dyn(struct array_stack *stack, void *in_data)
{
    void *new_p = NULL;

    if (stack == NULL)
        return -1;

    /* stack is full */
	if(ARRAY_STACK_IS_FULL(stack))
    {
        new_p = ARRAY_STACK_CALLOC(1, (2 * stack->size * stack->tpsz));
        if (new_p == NULL)
            return -1;

        memcpy(new_p, stack->p, stack->size * stack->tpsz);
        ARRAY_STACK_FREE(stack->p);
        stack->p = new_p;
        stack->size *= 2;
        return array_stack_push(stack, in_data);
    }
    else
    {
        return array_stack_push(stack, in_data);
    }
}

六、栈删除

/**
 * delete array stack space.
 * 
 * @param array_stack: array stack
 * @return -1: fail
 *          0:success
 */
int array_stack_empty(struct array_stack *stack)
{
	if (stack == NULL)
		return -1;

    /* free array stack space */
    if (stack->p != NULL)
    {
        ARRAY_STACK_FREE(stack->p);
        stack->p = NULL;
    }
	
	return 0;
}

七、栈销毁

/**
 * delete and destroy an array stack.
 * 
 * @param array_stack: array stack
 * @return -1: fail
 *          0:success
 */
int array_stack_destory(struct array_stack *stack)
{
    if (array_stack_empty(stack) != 0)
        return -1;

    ARRAY_STACK_FREE(stack);
	stack = NULL;
		
    return 0;
}

八、验证程序

struct array_stack *array_stack_head;
int array_stack_w[5] = {11,22,33,44,55};
int array_stack_r[5] = {0};
void array_stack_test(void)
{
	array_stack_head = array_stack_creat(5, sizeof(int));
	
	array_stack_push(array_stack_head, (void*)&array_stack_w[0]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[1]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[2]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[3]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[4]);
	
	array_stack_pop(array_stack_head, (void*)&array_stack_r[0]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[1]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[2]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[3]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[4]);
	
	array_stack_push(array_stack_head, (void*)&array_stack_w[0]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[0]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[1]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[1]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[2]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[2]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[3]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[3]);
	array_stack_push(array_stack_head, (void*)&array_stack_w[4]);
	array_stack_pop(array_stack_head, (void*)&array_stack_r[4]);
}
发布了35 篇原创文章 · 获赞 22 · 访问量 1148

猜你喜欢

转载自blog.csdn.net/m0_37845735/article/details/103317265