栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除的操作,进行数据插入和删除操作的一端叫栈顶,另一端叫栈底,另外,栈遵循先进后出的操作。
以下是用数组实现栈的方法:
1.创建栈的结构体
typedef int StackType;
typedef struct stack
{
StackType* arrdata;
int capacity;
int point;
}stack;
“arrdata”是数组指针,“capacity”记录栈的容量,“ point”指向栈顶元素的下一个。
2.初始化栈
//初始化
void StackInit(stack* pstack)
{
assert(pstack);
pstack->capacity = 0;
pstack->arrdata = 0;
pstack->point = 0;
}
3.销毁栈
//销毁
void StackDestroy(stack* pstack)
{
assert(pstack);
free(pstack->arrdata);
pstack->capacity = 0;
pstack->point = 0;
}
4.入栈
//入栈
void StackPush(stack* pstack, StackType data)
{
assert(pstack);
//判断是否需要扩容
if (pstack->capacity == pstack->point)
{
int newcappacity = pstack->capacity == 0 ? 4 : pstack->capacity * 2;
StackType* newstack = (StackType*)realloc(pstack->arrdata, newcappacity * sizeof(StackType));
if (newstack == NULL)
{
perror("realloc error!");
return;
}
pstack->arrdata = newstack;
pstack->capacity = newcappacity;
}
//写入数据
pstack->arrdata[pstack->point] = data;
pstack->point++;
}
为了防止数组大小不够用,因此这里使用了动态内存管理来进行扩容。
5.出栈
//出栈
void StackOut(stack* pstack)
{
assert(pstack->point > 0);
pstack->point--;
}
这里只需要减小point的指向就可以实现出栈,因为我们访问栈顶是用point来进行的。
6.判空
//检查是否为空
bool CheckEmpty(stack* pstack)
{
assert(pstack);
return pstack->point == 0;
}
由于point是指向栈顶的下一个元素,当point为0;就代表栈为空,此时pstack->point == 0;为真,便返回真。
7.获取栈的元素个数
//获取栈的元素个数
int GetStackNum(stack* pstack)
{
assert(pstack);
return pstack->point;
}
8.获取栈顶元素
//获取栈顶元素
StackType GetStackTopElement(stack* pstack)
{
assert(pstack);
assert(pstack->point > 0);
return pstack->arrdata[pstack->point - 1];
}
9.测试
#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"
void text()
{
stack mystack;//创建栈
StackInit(&mystack);
for (int i = 0; i < 100; i++)
{
StackPush(&mystack,i);
}
while (!CheckEmpty(&mystack))
{
printf("%d ", GetStackTopElement(&mystack));
StackOut(&mystack);
}
StackDestroy(&mystack);
}
int main()
{
text();
return 0;
}
结果如下:
由此可见,这个栈遵循先进后出