目录
栈与队列的本质
栈与队列都是属于线性表,那么它们的逻辑结构必定是线性结构的,线性表的概念可以参见
数据结构之线性表,它们的物理结构依赖于它们的实现方式
栈的基本概念
栈(Stack):是只允许在一端进行插入或者删除操作的线性表。
栈一共有两端:
允许进行插入删除的那一端称为栈顶(Top)
固定的,不允许进行插入删除的另一端称为栈底(Bottom)
因此栈具有后进先出的特性
压栈:栈的插入操作,入数据在栈顶。
出栈:栈的删除操作,出数据也在栈顶。
入栈、出栈的方式与栈顶指针的初始化不同而有所不同
下面是栈顶指针初始化为-1的情况
a、栈空时
b、入栈与出栈的过程
进栈操作:栈不满时,栈顶指针先加1,再送值到栈顶元素;
出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1。
下面是栈顶指针初始化为0的情况
栈的物理结构
栈的物理结构依赖于它的实现,栈可以用数组或者链表实现,使用数组实现其物理结构是连续的,使用链表实现其物理结构非连续的。相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。(栈的实现推荐用数组)
栈的顺序存储结构(用数组实现)
采用顺序存储的栈称为顺序栈,其又分为
静态栈:使用定长数组实现
动态栈:使用动态开辟的数组实现
静态栈不实用,因为栈需要进行大量的入栈与出栈操作,静态栈的空间大小难以改变,容易出现空间不足或者大量空间浪费的情况,因此顺序栈一般指的就是动态栈的实现
静态栈的实现:
实现的思路:
1、静态栈的定义
2、栈的初始化
3、判空(判断栈是否为空)、进栈、出栈、取栈顶元素
在visual studio 2017下新建一个工程,并建立三个文件如图
Stack.h中
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
//静态栈:采用定长数组实现的栈
#define MaixSize 100
typedef int StackDataType;
typedef struct Stack
{
StackDataType _array[MaixSize];//定长数组
int _top;//表示栈顶指针,该栈顶指针是抽象化的概念,用_top整型变量就可以表示了
}Stack;
void StackInit(Stack*pStack);//栈的初始化
bool StackIsEmpty(Stack*pStack);//判断栈是否为空
void StackPush(Stack*pStack, StackDataType data);//入栈
StackDataType StackPop(Stack*pStack);//出栈
StackDataType StackGetTop(Stack *pStack);//获取栈顶元素
Test/c中
#include"Stack.h"
void Test()
{
Stack S;
StackInit(&S);
printf("S._top=%d\n", S._top);
printf("0表示栈不为空,1表示空:");
printf("%d\n", StackIsEmpty(&S));
printf("**************************\n");
printf("入栈:\n");
StackPush(&S, 1);
printf("栈顶元素:%d\n", StackGetTop(&S));
printf("**************************\n");
printf("入栈:\n");
StackPush(&S, 2);
printf("栈顶元素:%d\n", StackGetTop(&S));
printf("**************************\n");
printf("入栈:\n");
StackPush(&S, 3);
printf("栈顶元素:%d\n", StackGetTop(&S));
printf("**************************\n");
printf("入栈:\n");
StackPush(&S, 4);
printf("栈顶元素:%d\n", StackGetTop(&S));
printf("**************************\n");
printf("入栈:\n");
StackPush(&S, 5);
printf("S._top=%d\n", S._top);
printf("0表示栈不为空&