目录
一:栈和队列
1.1 一般定义和特点
引:说到栈就不得不提到队列,这是两种特殊的线性表
- 栈和队列是两种常用的、重要的数据结构
- 栈和队列是限定插入和删除只能在表的"端点”进行的线性表
栈的后进先出的特点 :比如:弹夹 洗盘子
1.2 栈的应用
■数制转换 ■表达式求值
■括号匹配的检验 ■八皇后问题
■行编辑程 ■函数调用
■迷宫求解 ■递归调用的实现
二:栈的定义和特点
2.1 定义
■ 栈(stack) 是一个特殊的线性表,是限定仅在一端(通常是表尾)进行插入和删除操作的线表。
■ 又称为后进先出(Last In First Out)的线性表,简称LIFO结构。
心中有图 撸码自然神
2.2 栈的相关概念
2.2.1 结构和操作
Top:表尾(即a,端)称为栈顶
Base:表头(即an端)称为栈底
PUSH:插入元素到栈顶的操作 称为入栈
POP:从栈顶(即表尾)删除最后一个元素的操作 称为入栈
2.2.2 相关概念
1.定义 限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作)
2.逻辑结构 与同线性表相同,仍为-对一关系。
3.存储结构 用顺序栈戟链栈存储均可,但以顺序栈更常见
4.运算规则 只能在栈顶运算,且访问结点时依照后进先出(LIFO) 的原则。
5.实现方式 关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同。
2.2.3 栈与一般线性表有什么不同?
2.3 栈的一般操作图示:
三 :栈的操作 (顺序栈和链栈)
3.1 栈的抽象数据类型的类型定义:
一般重要操作
3.2 顺序栈的表示和实现代码
3.2.1 注意:top base的一些注意事项
1: top指向栈顶元素之上
2:stacksize 表示栈可使用的最大容量
3:栈空标志?base = top 栈满标志?top - base = stacksize
4: 下溢和上溢 上溢:栈满,还需要压入元素 || 下溢:栈空 还需要弹出元素
注:上溢一般认为是一种错误 ,下溢一般认为是结束条件,即问题结束
3.2.2 顺序栈的表示
#define MAXSIZE 100
typedef struct{
SElemType *base; //栈底
SElemType *top; //栈顶
int stacksize; //栈可用最大容量
}SqStack;
3.2.3 顺序栈的初始化
Status InitStack(SqStack &S){ //创建一个空栈
S.base = (SElemType*)malloc(sizeof(SElemType));
if(!S.base)exit(OVERFLOW); //存储分配失败
S.top = S.base; //栈顶指针 等于 栈底指针
S.stacksize = MAXSIZE;
return OK;
}
3.2.4 顺序栈判断栈是否为空
Status StackEmpty(SqStack S){
// 若栈为空 返回TRUE
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
3.2.5 求顺序栈长度 和 清空栈 销毁栈
int StackLength(SqStack S){
return S.top-S.base;
}
Status ClearStack(SqStack S){
if(S.base) S.top = S.base;
return OK;
}
Status DestroyStack(SqStack &S){
if(S.base){
delete S.base;
S.base =S.top =NULL;
S.stacksize =0;
}
return OK;
}
3.2.6 顺序栈的入栈 Push
第一种可能:未满
第二种可能:栈满
所以 需要先判断
算法思想:
Status push(SqStack &S,SElemType e){
if(S.top-S.base==stacksize) return ERROR; //栈满
*S.top ++=e;//* 对所指空间的操作 ||对指针所指的值的直接操作
return OK;
}
3.2.7 顺序栈的出栈 Pop
一般情况
特殊情况
所以需要判断 栈是否为空
算法思想:
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e = *-- S.top;
return OK;
}
3.3 栈链的操作和代码
3.3.1 链栈的表示
■ 链栈是运算受限的单链表,只能在链表头部进行操作
typedef struct StackNode{
SELemType data;
struct StackNode *next;
}StackNode, *LinkStack;
LinkStack S; //尾指针
向下的 why?
总结:
3.3.2 链栈的初始化
void InitStack(LinkStack &S){
//构建一个空栈 头指针为空
S=NULL;
return OK;
}
3.3.3 判断链栈是否为空
Status StackEmpty(LinkStack S){
if(S==NULL)return TRUE;
else return FALSE;
}
3.3.4 链栈的入栈
Status Push(SqStack &S,SElemtype e){
p = (LinkStack)malloc(sizeof(StackNode));
p->data =e; //新节点数据域 置为e
p->next =S;// 将新节点插入栈顶
S=p;//修改栈顶指针
return OK;
}
3.3.5 链栈的入栈
Status Pop(LinkStack &S,SElemType &e){
if(S==NULL) return ERROR;
//S->next =S->next->next;
e = S->data;
p = S;
S = S->next;
delete p;
return OK;
}
3.3.6 取栈顶元素
SElemType GetTop(LinkStack S){
if(S!=NULL)
return S->data;
}
四:栈与递归
4.1 递归的定义:
- 若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的;
- 若一个过程真接地或间接地调用角己,则称这个过程是递归的过程。