栈的核心思想就是,先入后出,作为复习,我决定用C语言实现一下栈的基本操作
想清楚栈顶指针的位置,以及栈空间不够时要增加栈空间,其他方面都不是很复杂,直接贴代码,有简单注释
//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
我分别对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;
}