簡單的棧

棧是一種常見的數據結構,主要特點是“後進先出”。以下是用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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章