[数据结构 & 算法] C语言实现栈容器

1、栈

栈的核心思想就是,先入后出,作为复习,我决定用C语言实现一下栈的基本操作

  1. Init 初始化
  2. Destroy 销毁
  3. Clear 清除
  4. Length 获得栈的长度
  5. Empty 是否为空
  6. Top 取栈顶元素
  7. Pop 出栈
  8. Push 入栈
  9. Iterator 对栈进行遍历

想清楚栈顶指针的位置,以及栈空间不够时要增加栈空间,其他方面都不是很复杂,直接贴代码,有简单注释

//Stack.h
//author: 芒果和小猫

#include 
#define SElemType int//定义栈里存储的数据类型
#define STACKINITSIZE 50//栈初始的大小
#define STACKINCREAMENT 50//每次栈增加的大小

typedef struct 
{
	SElemType* base;//指向栈底,也就是第一个元素
	SElemType* top;//指向栈顶元素的下一个
	int stackSize;//当前栈的空间大小,就是可以放多少个定义的数据类型
}Stack;

typedef int(*StackVisit)(SElemType* element);//函数指针,对栈里的元素进行操作

/*初始化栈*/
int InitStack(Stack* stack)
{
	//给栈分配空间,malloc是从堆里取空间,要手动归还
	stack->base = (SElemType*)malloc(STACKINITSIZE * sizeof(SElemType));
	if (stack->base == NULL)
		return 0;
	stack->top = stack->base;
	stack->stackSize = STACKINITSIZE;
	return 1;
}

void DestroyStack(Stack* stack)
{
	//归还分配的空间
	free(stack->base);
	stack->base = NULL;
	stack->top = NULL;
	stack->stackSize = 0;
}

void ClearStack(Stack* stack)
{
	//清除栈元素,也就是将栈顶移到栈底
	stack->top = stack->base;
}

int StackEmpty(Stack* stack)
{
	if (stack->base == stack->top||stack->top==NULL)
		return 1;
	else
		return 0;
}

int StackLength(Stack* stack)
{
	if (stack->base == NULL)
		return 0;
	else
		return stack->top - stack->base;
}

SElemType StackGetTop(Stack* stack)
{
	//因为top指向的顶上元素的下一个,所以要-1
	if (!StackEmpty(stack))
		return *(stack->top - 1);
	else
		return NULL;
}

int StackPush(Stack* stack,SElemType element)
{
	//如果空间不够要重新分配空间
	if (StackLength(stack) >= stack->stackSize)
	{
		stack->base = (SElemType*)realloc(
		stack->base,(stack->stackSize + STACKINCREAMENT) * sizeof(SElemType));
		if (stack->base == NULL)
			return 0;
		stack->top = stack->base + stack->stackSize;
		stack->stackSize += STACKINCREAMENT;
	}
	*stack->top = element;
	stack->top++;
}

SElemType StackPop(Stack* stack)
{
	if (StackEmpty(stack))
		return NULL;
	stack->top--;
	return *(stack->top);
}

//以下提供一下对栈遍历可以用的迭代器
SElemType* StackBegin(Stack *stack)
{
	return stack->base;
}
SElemType* StackEnd(Stack *stack)
{
	return stack->top;
}

//传入一个函数指针,对栈中的所有元素进行操作
int StackTraverse(Stack* stack, StackVisit visit)
{
	SElemType *iter;
	for (iter = StackBegin(stack); iter!= StackEnd(stack); iter++)
	{
		if(visit(iter)==0)
			return 0;
	}
	return 1;
}

#undef SElemType

2、测试

我分别对int类型和char类型做了简单的测试,代码如下

#include 
#include 
#include "Stack.h"


int StackPrintInt(int* e)
{
	if (*e > 3)
	{
		printf("%d > 3\n", *e);
	}
	return 1;
}

int StackPrintChar(char* e)
{
	if (*e > 'a')
	{
		printf("%c > a\n", *e);
	}
	return 1;
}

//当数据是int时,测试
void testInt()
{
#define SElemType int
	Stack s;
	printf("Stack Init\n");
	InitStack(&s);
	printf("Stack Push : 5\n");
	printf("Stack Push : 4\n");
	printf("Stack Push : 3\n");
	printf("Stack Push : 2\n");
	printf("Stack Push : 1\n");
	StackPush(&s, 5);
	StackPush(&s, 4);
	StackPush(&s, 3);
	StackPush(&s, 2);
	StackPush(&s, 1);
	printf("Stack Length : %d\n", StackLength(&s));
	printf("Stack Top : %d\n", StackGetTop(&s));
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Traverse : \n");
	StackTraverse(&s, StackPrintInt);
	printf("Stack Pop : \n");
	while (!StackEmpty(&s))
	{
		printf("%d\n", StackPop(&s));
	}
	printf("Stack Push : 1\n");
	StackPush(&s, 1);
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Clear\n");
	ClearStack(&s);
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Length : %d\n", StackLength(&s));
	if (StackGetTop(&s) == NULL)
		printf("Stack Top is NULL\n");
	if (StackPop(&s) == NULL)
		printf("Stack Pop is NULL\n");
	printf("Stack Push : 10\n");
	StackPush(&s, 10);
	printf("Stack Push : 20\n");
	StackPush(&s, 20);
	printf("Stack Push : 30\n");
	StackPush(&s, 30);
	printf("Stack Iterator\n");
	for (SElemType* it = StackBegin(&s); it != StackEnd(&s); it++)
	{
		printf("%d\n", *it);
	}
	DestroyStack(&s);
	InitStack(&s);
	for (int i = 0; i < 300; i++)
	{
		StackPush(&s, i);
	}
	printf("Test Stack Increament\n");
	while (!StackEmpty(&s))
	{
		printf("%d ", StackPop(&s));
	}
#undef SElemType
}

//当数据时char时,测试
void testchar()
{
#define SElemType int
	Stack s;
	printf("\nStack Init\n");
	InitStack(&s);
	printf("Stack Push : a\n");
	printf("Stack Push : b\n");
	printf("Stack Push : c\n");
	printf("Stack Push : d\n");
	printf("Stack Push : e\n");
	StackPush(&s, 'a');
	StackPush(&s, 'b');
	StackPush(&s, 'c');
	StackPush(&s, 'd');
	StackPush(&s, 'e');
	printf("Stack Length : %d\n", StackLength(&s));
	printf("Stack Top : %c\n", StackGetTop(&s));
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Traverse : \n");
	StackTraverse(&s, StackPrintChar);
	printf("Stack Pop : \n");
	while (!StackEmpty(&s))
	{
		printf("%c\n", StackPop(&s));
	}
	printf("Stack Push : a\n");
	StackPush(&s, 'a');
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Clear\n");
	ClearStack(&s);
	printf("Stack Empty : %d\n", StackEmpty(&s));
	printf("Stack Length : %d\n", StackLength(&s));
	if (StackGetTop(&s) == NULL)
		printf("Stack Top is NULL\n");
	if (StackPop(&s) == NULL)
		printf("Stack Pop is NULL\n");
	printf("Stack Push : f\n");
	StackPush(&s, 'f');
	printf("Stack Push : g\n");
	StackPush(&s, 'g');
	printf("Stack Push : w\n");
	StackPush(&s, 'w');
	printf("Stack Iterator\n");
	for (SElemType* it = StackBegin(&s); it != StackEnd(&s); it++)
	{
		printf("%c\n", *it);
	}
#undef SElemType
}
int main(int argc, char *argv[]) {
	
	testInt();
	testchar();
	return 0;
}

3、测试结果

关于int类型的测试结果

[数据结构 & 算法] C语言实现栈容器_第1张图片

关于char类型的测试结果

[数据结构 & 算法] C语言实现栈容器_第2张图片

4、参考

  1. 数据结构C语言版(严蔚敏)

你可能感兴趣的:(数据结构,C,栈)