目录
1.认识栈:
记住栈的以下特点:
1.先进先出
2.只可从最上面的元素出栈,不能从底下出去。
2.栈的实现:
由上可知,栈可以是多种实现方法,可以是链表,也可以是顺序表,这里我们用顺序表实现:
预处理:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int StackDataType;
typedef struct Stack
{
StackDataType* arr;
int top;
int capacity;
}ST;
top是用来记录栈顶,capacity是用来记录栈内的容量大小。
3.初始化、创建、销毁:
初始化没什么好说的。
销毁是肯定的,不然会造成内存的浪费。
void StackInit(ST* p)
{
assert(p);
p->arr = (StackDataType*)malloc(4*sizeof(StackDataType));
p->capacity = 4;
p->top = -1;
}
void StackDestory(ST* p )
{
assert(p);
free(p->arr);
p->arr = NULL;
p->capacity = 0;
p->top = -1;
}
值得一提的是,这里的top既可以设置成0,也可以设置成-1.
设置成0就是记录栈顶的后一个元素,设置成-1就是记录栈的当前元素,并且两种方法入栈略有差异
4.出入栈:
从上面可以知道,出入站遵循先进先出的特点,结合上面说的-1\0之间的差异,以下这样实现:
void StackPush(ST* p, StackDataType x)
{
assert(p);
p->top++;
if (p->capacity == p->top)
{
StackDataType* temp = (StackDataType*)realloc(p->arr, 2 * p->capacity * sizeof(StackDataType));
if (temp == NULL)
{
printf("malloc failed!\n");
}
else
{
p->capacity *= 2;
p->arr = temp;
}
}
p->arr[p->top] = x;
}
void StackPop(ST* p)
{
assert(p);
assert(p->top > -1);
p->top--;
}
解释:为什么出栈没有真正的出?有些人可能认为直接把栈顶元素赋值成0,这样做是有所缺陷的.
比如你栈里面存放的是结构体变量怎么办??所以可以直接采取这种粗暴的方法。
5.栈的大小,是否为空:
int StackSize(ST* p)
{
assert(p);
return ++p->top;
}
bool StackEmpty(ST* p)
{
if (p->top == -1)
return true;
else
return false;
}
问题:这里的top为什么要++才能返回?
因为我们这里top初始化是-1,记录的是当前栈顶元素位置,比如只有一个元素,那么top就是0显然不合理。
6.栈顶元素查询:
这个太水了,没什么多说的:
StackDataType StackTop(ST* p)
{
assert(p);
assert(p->top >= 0);
return p->arr[p->top];
}
以上就是栈的一些碎碎念。