栈的结构和概念
栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端称为栈底,栈中元素遵循先出后进的顺序
压栈:插入元素
出栈:删除元素
生活中栈的实例:羽毛球筒,吃东西吐出来等等。
栈的实现
实现栈的相关功能时,由于栈的特性我们进行分析后,栈的底层结构可以形成一段连续的空间,可对其进行尾插尾删的操作。
这里我们实现的是支持动态增长的栈结构,静态栈结构不常用到
(1)初始化栈
void StackInit(Stack* ps)// 初始化栈
{
assert(ps);
ps->array = (STDataType*)malloc(sizeof(STDataType) * 10);
if (NULL == ps->array)
{
assert(0);
return;
}
ps->capacity = 10;
ps->top = 0;
}
(2)检查栈容量
void CheckCapacity(Stack* ps)//检查容量
{
assert(ps);
if (ps->top == ps->capacity)
{
//1.开辟新空间
STDataType* newCapacity = (STDataType*)malloc(sizeof(STDataType)*ps->top * 2);
if (newCapacity == NULL)
{
assert(0);
return;
}
//2.拷贝元素
memcpy(newCapacity, ps->array, sizeof(STDataType)*ps->top);
//3.释放旧空间
free(ps->array);
//4.使用新空间
ps->array = newCapacity;
ps->capacity *= 2;
}
}
(3)入栈
相当于顺序表中的尾插操作
void StackPush(Stack* ps, STDataType data)// 入栈
{
assert(ps);
CheckCapacity(ps);
ps->array[ps->top++] = data;
}
(4)出栈
相当于顺序表中的尾删操作
void StackPop(Stack* ps)// 出栈
{
if (StackEmpty(ps))
return;
ps->top--;
}
(5)获取栈顶元素操作
STDataType StackTop(Stack* ps)// 获取栈顶元素
{
assert(!StackEmpty(ps));
return ps->array[ps->top - 1];
}
(6)获取栈中有效元素个数
int StackSize(Stack* ps)// 获取栈中有效元素个数
{
assert(ps);
return ps->top;
}
(7)检测栈是否为空
int StackEmpty(Stack* ps)// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
{
assert(ps);
return ps->top == 0;
}
(8)销毁栈
void StackDestroy(Stack* ps)// 销毁栈
{
assert(ps);
free(ps->array);
ps->array = NULL;
ps->capacity = 0;
ps->top = 0;
}
这次依然将主要的代码分成了三个源文件,Stack.c,test.c,Stack.h,其中Stack.c实现代码中的各个函数,test.c实现顺序表的相关测试,Stack.h实现用到的各种头文件与函数声明。
Stack.h
#pragma once
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* array;
int top; // 栈顶/栈中的元素个数
int capacity; // 容量
}Stack;
void StackInit(Stack* ps);// 初始化栈
void StackPush(Stack* ps, STDataType data);// 入栈
void StackPop(Stack* ps);// 出栈
STDataType StackTop(Stack* ps);// 获取栈顶元素
int StackSize(Stack* ps);// 获取栈中有效元素个数
int StackEmpty(Stack* ps);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
void StackDestroy(Stack* ps);// 销毁栈
Stack.c
#include <stdio.h>
#include "Stack.h"
#include <assert.h>
#include <malloc.h>
#include <string.h>
void StackInit(Stack* ps)// 初始化栈
{
assert(ps);
ps->array = (STDataType*)malloc(sizeof(STDataType) * 10);
if (NULL == ps->array)
{
assert(0);
return;
}
ps->capacity = 10;
ps->top = 0;
}
void CheckCapacity(Stack* ps)//检查容量
{
assert(ps);
if (ps->top == ps->capacity)
{
//1.开辟新空间
STDataType* newCapacity = (STDataType*)malloc(sizeof(STDataType)*ps->top * 2);
if (newCapacity == NULL)
{
assert(0);
return;
}
//2.拷贝元素
memcpy(newCapacity, ps->array, sizeof(STDataType)*ps->top);
//3.释放旧空间
free(ps->array);
//4.使用新空间
ps->array = newCapacity;
ps->capacity *= 2;
}
}
void StackPush(Stack* ps, STDataType data)// 入栈
{
assert(ps);
CheckCapacity(ps);
ps->array[ps->top++] = data;
}
void StackPop(Stack* ps)// 出栈
{
if (StackEmpty(ps))
return;
ps->top--;
}
STDataType StackTop(Stack* ps)// 获取栈顶元素
{
assert(!StackEmpty(ps));
return ps->array[ps->top - 1];
}
int StackSize(Stack* ps)// 获取栈中有效元素个数
{
assert(ps);
return ps->top;
}
int StackEmpty(Stack* ps)// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
{
assert(ps);
return ps->top == 0;
}
void StackDestroy(Stack* ps)// 销毁栈
{
assert(ps);
free(ps->array);
ps->array = NULL;
ps->capacity = 0;
ps->top = 0;
}
test.c
#include "Stack.h"
int main()
{
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
StackPush(&s, 5);
StackPush(&s, 6);
StackPush(&s, 7);
printf("%d\n", StackTop(&s));
printf("%d\n", StackSize(&s));
return 0;
}