数据结构 - 栈的学习

栈 (Stack) 是一种非常常见的数据结构, 是一种 "先入后出"(First In Last Out, FILO)  "后进先出" 的数据结构 (Last In First Out,  LIFO)。  也可以把栈看成是一种特殊的线性表,只能在栈顶进行插入和删除操作。 也就是说,对于栈而言,你只能在栈顶进行操作,而栈底是固定的

栈的基本操作,包括 入栈(Push), 出栈(Pop), 取栈顶元素(Top) , 判空 (IsEmpty) 等

栈有顺序栈和链式栈

1. 顺序栈

我们来看看顺序栈的示意图:

 

顺序栈是一种使用数组实现的栈,也称为数组栈, 也就是说,它是通过数组来存储栈中的元素的, 并且通过栈顶指针来指示栈顶元素在数组中的位置。 顺序栈具有以下特点:

1. 存储结构: 顺序栈使用数组来作为底层的存储结构,栈中的每个元素会作为数组中的一个元素存在

2. 操作顺序:  栈只能够从栈顶插入和删除元素,不支持在栈中间插入和删除元素

3. 顺序访问:  只能从栈顶开始访问栈中的元素,不能从栈底或者中间位置来访问元素

 

 由上面可以看出,顺序栈的实现并不是很难,我们可以通过数组和栈顶指针两个变量来进行实现。 它的一些主要操作包括 初始化,入栈,出栈,获取栈顶元素,判断栈是否为空, 以及获取栈中元素的数量等。 

上面也提到,顺序栈的存储结构是数组,因此我们使用时也需要考虑数组大小的限制,当栈中元素数量超过数组大小时,需要对数组进行扩容

时间复杂度:

 遍历栈中元素的操作时间复杂度为 O(n)

入栈,出栈,获取栈顶元素,判断栈是否为空   =>  这几个操作时间复杂度为 O(1)

 

现在,我用C++来实现栈的这些基本操作

1. 用结构来定义一个栈

// 栈中的数据类型
typedef int stackType;
#define INITCAPA 5
//栈结构 typedef struct Stack{ stackType *arr; //数组 int top; //栈顶 int capacity; //栈的容量 } ST;

 

2. 初始化栈

void StackInit(ST *pst)
{
assert(pst);
pst->arr = (stackType *)malloc(INITCAPA * sizeof(stackType));
if(pst->arr == NULL)
{
perror("malloc fail");
return;
}
pst->top = 0; // top等于0,指的是栈顶元素的下一个位置
// pst->top = -1; //指的是栈顶元素的位置
pst->capacity = INTICAPA; }

 3. 判断空栈

因为在第2步中pst->top赋的初值为0. 所以当 top == 0 时,就表示栈为空

bool StackEmpty(ST* pst)
{
assert(pst);
return pst->top == 0; }

4. 入栈

入栈,需要先判断栈满没满,满的条件为 ptr->top == ptr->capacity, 如果栈已经满了,我们还想有元素入栈,那么就需要对栈进行扩容。 扩容的过程和顺序表是一样的

从上面第2步可以知道,top表示的是栈顶元素的下一个位置,所以在top下标处位置进行插入数据就可以。 完成后进行 top++就可以完成一次入栈了

void STPush(ST* pst, stackType newElement)
{
assert(pst);
if(pst->capacity == pst->top)
{
stackType* tmp = (stackType*)realloc(pst->arr, sizeof(stackType) * pst->capacity * 2);
if(tmp == NULL)
{
perror("realloc fail");
return;
}
pst->arr = tmp;
pst->capacity *= 2;
}
pst->arr[pst->top] = newElemenet;
pst->top++; }

5. 出栈

出栈,如果栈为空,出栈就会出问题,所以出栈前,我们需要判断一下,栈不为空

上面提到,入栈后top++, 显然,出栈就是top--, 也就是说我们进行 pst->top--, top值减去1,那么在其他所有操作中就访问不到最后一个元素了,也就达到了出栈的效果

void STPop(ST* pst)
{
assert(pst);
assert(!
StackEmpty(pst));
pst->top--;
}

6. 获取栈顶元素的值

获取栈顶元素的值,显然有个前提条件那就是栈中得有元素存在。如果栈是个空栈,那什么也获取不到,所以获取之前,还是需要使用上面自己写的StackEmpty方法判断一下

从上面可以知道,top表示栈顶元素的下一个位置,所以 top -1才表示栈顶元素的下标, 也就是 pst->arr[pst->top - 1] , 代码如下

stackType STTop(ST* pst)
{
assert(pst);
assert(!StackEmpty(pst));
return pst->arr[pst->top -1];

}

 7, 销毁

void STDestory(ST* ptr)
{
assert(ptr);
free(ptr->arr);
ptr->arr == NULL;
ptr->capacity = 0;
ptr->top = 0; }

 

posted on 2024-03-22 14:39  新西兰程序员  阅读(17)  评论(0编辑  收藏  举报