前言
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端
称为栈顶,另一端称为栈底。
栈中的数据元素遵守后进先出
LIFO
(
Last In First Out
)的原则。
压栈:栈的插入操作叫做进栈
/
压栈
/
入栈,
入数据在栈顶
。
出栈:栈的删除操作叫做出栈。
出数据也在栈顶
。
虽然是后进先出,但是可能不入完就开始出,导致顺序多种多样。
数组的结构实现栈比较方便,因为栈的插入删除都在栈顶,数组尾部插入删除非常方便,把尾部当成栈顶。
今天是用数组实现栈,依然是分为stack.h文件和stack.c文件。
一、stack.h
#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
//Top指向栈顶元素的下一个位置,那么top初始值就是0,top的值与栈中元素个数是相等的
//存一个指针指向一个数组,top指向栈顶元素的下一个位置。Capacity表示容量
typedef int Datatype;
typedef struct Stack
{
Datatype* a;
int top;
int capacity;
}ST;
void Init(ST* st);
void Destroy(ST* st);
void Push(ST* st,Datatype x);
void Pop(ST* st);
Datatype Top(ST* st);
int Size(ST* st);
二、stack.c
1.初始化
void Init(ST* st)
{
assert(st);
st->a = NULL;
st->capacity = 0;
st->top = 0;//指向栈顶元素的下一个位置
}
初始化时把a初始化为空,top由于指向栈顶元素的下一个位置,整成0,容量一开始也是0
2.释放
void Destroy(ST* st)
{
assert(st);
free(st->a);
st->a = NULL;
st->capacity = 0;
st->top = 0;
}
摧毁时,释放a指向的数组,并且置空防止野指针,将top和capacity置0
3.入栈
void Push(ST* st,Datatype x)
{
assert(st);
if (st->top == st->capacity)
{
int newcapacity = st->capacity ==0 ? 4 : 2 * st->capacity;
Datatype*tmp=(Datatype*)realloc(st->a,sizeof(Datatype) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
}
st->a = tmp;
st->capacity = newcapacity;
}
st->a[st->top] = x;
st->top++;
}
入栈时先检查容量,满了就扩容
然后改变栈顶元素,top++
不专门写一个扩容函数的原因是只有入栈时会用到扩容
4.出栈
void Pop(ST* st)
{
assert(st);
assert(!Empty(st));
st->top--;
}
删除时先检查是否为空
然后top--
5.判空
bool Empty(ST* st)
{
assert(st);
return st->top == 0;
}
当top为0时说明数据个数为0,栈为空
6.获取数据个数
int Size(ST* st)
{
assert(st);
return st->top;
}
top指向栈顶元素的下一个位置,top==size
7.获取栈顶元素
Datatype Top(ST* st)
{
assert(st);
assert(!Empty(st));
return st->a[st->top - 1];
}
由于top指向栈顶元素的下一个位置,所以要取top位置的上一个数据
8.stack.c
#include"stack.h"
void Init(ST* st)
{
assert(st);
st->a = NULL;
st->capacity = 0;
st->top = 0;//指向栈顶元素的下一个位置
}
void Destroy(ST* st)
{
assert(st);
free(st->a);
st->a = NULL;
st->capacity = 0;
st->top = 0;
}
void Push(ST* st,Datatype x)
{
assert(st);
if (st->top == st->capacity)
{
int newcapacity = st->capacity ==0 ? 4 : 2 * st->capacity;
Datatype*tmp=(Datatype*)realloc(st->a,sizeof(Datatype) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
}
st->a = tmp;
st->capacity = newcapacity;
}
st->a[st->top] = x;
st->top++;
}
bool Empty(ST* st)
{
assert(st);
return st->top == 0;
}
void Pop(ST* st)
{
assert(st);
assert(!Empty(st));
st->top--;
}
Datatype Top(ST* st)
{
assert(st);
assert(!Empty(st));
return st->a[st->top - 1];
}
int Size(ST* st)
{
assert(st);
return st->top;
}
总结
这就是栈的数组实现方式,比较简单。