数据结构---栈的实现
一、栈的定义
1、栈是限定仅在表尾进行插入删除操作的线性操作。
(栈类似于子弹弹夹中的子弹一样,先进去的后出来,后进去的要先出来。)
在我们软件应用中,栈这种后进先出的数据结构是非常普。比如你用浏览器上网时,不管用什么浏览器,都有一个“后退键”,你单击后可以按访问顺序的逆序加载浏览过的网页。再一个撤销操作也是用栈这样的方式实现的。
2、我们把允许插入和删除的一端称之为栈顶(top),另一端称作栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last in First Out)的线性表,简称:LIFO结构。
3、栈是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。定义中说是在线性表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。
它的特殊之处就在于限制了这个线性表的的插入和删除位置,它始终只在栈顶进行,这也就使得:栈底是固定的,最先进栈的只能在栈底。
4、栈的插入操作,叫做进栈,也称为压栈,入栈;栈的删除操作,叫做出栈,也有的叫弹栈。
二、栈的实现
(这里我们用数组来实现,链表空间开销更大)
1、栈的初始化:
先定义栈的结构:
//定义栈的结构
typedef int STDatatype;
typedef struct Stack
{STDatatype* arr;int top;int capacity;}ST;
//初始化
void StackInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}
这里top用来标记栈顶元素在数组中的位置。
2、入栈
void StackPush(ST* ps, STDatatype x)
{assert(ps);if (ps->top == ps->capacity) {//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDatatype* tmp = (STDatatype*)realloc(ps->arr, newCapacity * sizeof(STDatatype));if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}ps->arr[ps->top++] = x;
}
3、销毁栈
//销毁
void StackDestroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}
4、判断栈是否为空
//判断栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
5、出栈
//出栈
void StackPop(ST* ps)
{assert(!StackEmpty(ps));--ps->top;
}
6、取栈顶元素
//取栈顶元素
STDatatype StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];
}
7、取栈顶有效元素
//获取栈中的有效元素
int StackSize(ST* ps)
{return ps->top;
}
三、栈的作用
栈的引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决的问题核心。