赞
踩
(考研真题待更新)
欢迎订阅专栏:408直通车
请注意,本文中的部分内容来自网络搜集和个人实践,如有任何错误,请随时向我们提出批评和指正。本文仅供学习和交流使用,不涉及任何商业目的。如果因本文内容引发版权或侵权问题,请通过私信告知我们,我们将立即予以删除。
限定仅在一端进行插入和删除操作的线性表,又称后进先出(LIFO)的线性表;
允许插入删除的那一端叫栈顶(Top),不允许插入和删除的一端叫栈底(Bottom)
注意:n个不同元素进栈,出栈元素不同排序个数为(n个元素能构成多少种不同的二叉树)
栈的顺序存储结构
顺序栈的基本结构
利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时设一个栈顶指针(Top)
基础结构
栈顶指针,初始值:S.top = -1(若有元素,则指向栈顶元素S.data[S.top])
进栈:栈不满时,栈指针先+1,再送值到栈顶
栈空条件:S.top == -1
栈满条件:S.top == MaxSize-1
顺序栈的基本操作
概念
原则
栈空判断:top0 = -1时0号栈为空,top1 = MaxSize时1号栈为空
栈满判断:两个栈顶指针相邻(即top1-top0 == 1)时
其他操作和顺序栈类似
栈的链式存储结构
采用单链表实现,并规定所有操作都是在单链表的表头进行
优点
是一种操作受限的线性表,只允许在表的一端进行插入(队尾),另一端进行删除(队头)
队头:删除元素的一端
分配一块连续的存储单元存放队列元素,设两个指针
基础结构
初始状态(队空条件):Q.front == Q.rear == 0
进队操作:队不满时,先送值到队尾元素,再将队尾指针+1
出队操作:队不空时,先取队头元素值,再将队头指针+1
假溢出:在data数组依然存在空位置时,却已经满足队列满的条件(出栈的元素位置空闲)
循环队列(解决假溢出问题)
概念
基本操作
初始时:Q.front = Q.rear = 0
队头指针+1:Q.front = (Q.front + 1) % MaxSize
队尾指针+1:Q.rear = (Q.rear + 1) % MaxSize
队列长度:(Q.rear + MaxSize - Q.front) % MaxSize
队空:Q.front == Q.rear
队满判断
牺牲一个单元来区分队空和队满,即队头指针在队尾指针的下一位置作为队满标志
类型中增设表示元素个数的数据成员(int size)
队空:Q.size == 0
队满:Q.size == MaxSize
类型中增设tag数据成员,以区分是队满还是队空
tag == 0时,若因删除导致Q.front == Q.rear,则队空
tag == 1时,若因插入导致Q.front == Q.rear,则队满
牺牲一个存储单元
队列的链式表示时一个同时带有队头指针和队尾指针的单链表
头指针指向队头结点,队尾指针指向队尾结点,当Q.front == NULL且Q.rear == NULL时,队列为空
不存在队列满且溢出问题,适合于数据元素变动较大的情况
概念
分类
输出受限的双端队列:允许在一端进行插入和删除,但在另一端只允许插入的双端队列
输入受限的双端队列:允许在一端进行插入和删除,但在另一端只允许删除的双端队列
括号匹配
步骤
初始设置一个空栈,顺序读入括号
若右括号,则从栈中弹出一个符号,判断是否匹配
若左括号,则压入栈中
失败条件
从左到右遍历各元素
若遇到操作数:直接加入后缀表达式
遇到界限符:“(”直接入栈;“)”则依次弹出栈内运算符并加入后缀表达式,直到弹出“(”为止
遇到运算符:依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止,之后再把运算符入栈
初始化操作数栈和运算符栈
若扫描到操作数,压入操作数栈;若扫描到运算符或界限符,按“中缀转后缀”的逻辑压入运算符栈(可能弹出运算符,若弹出则将栈顶的两个操作数运算压回操作数栈)
概念
若对象部分地包含自己,或用自己给自己定义,则称这个对象是递归的
若一个过程直接或间接的调用自己,则这个过程是递归的
分治的思想:必备条件
能将一个问题转变成一个新问题,且两者的解法相同或类似,不同的仅是对象,且对象有变化规律
可以通过上述转化将问题化简
必须有一个明确的递归出口(递归边界)
形式
概念
与线性表的关系
数组的存储结构
数组的所有元素在内存中占用一段连续的存储空间
一维数组
多维数组
按行优先(一行行存储)
按列优先(一列列存储)
指具有许多相同矩阵元素或0元素,并且这些相同矩阵元素或0元素的分布有一定规律
压缩矩阵
对称矩阵
概念
存储位置计算公式
三角矩阵
概念
(下/上)三角矩阵元素下标对应关系
下三角矩阵
上三角矩阵
(下/上)三角矩阵在内存中的压缩存储形式
下三角矩阵
上三角矩阵
三对角矩阵
概念
压缩存储:将元素按行优先方式存放在一维数组B中,且a(i, j)与B[n]对应关系为:k = 2i + j - 3
稀疏矩阵
概念
存储方式
三元组(行标、列标、值)
十字链表法
稀疏矩阵压缩存储后失去了随机存取的特性
循环队列注意点:队满与队空条件需要有区别,即需要一个额外的元素空间判断队空与队满
void push_q(int x){
if((tail + N + 1) % N != head){ //判断队满
q[tail] = x;
tail = (N + tail + 1) % N; //队尾插入一个数据注意指针移动需要%N,对头类似:head=(N+head+1)%N;
}
}
bool empty(){ //判断是否为空
return head == tail;
}
void pop_q(){ //对头删去一个元素
if(!empty())
head = (N + head + 1) % N;
}
void query(){ //查询对头元素
if(!empty())
printf("%d\n",q[head]);
}
应用场景:求某个数左边第一个小于他的数;
思路:在每次暴力从for循环的当前值,向左遍历找第一个小于数的O(n2)情况下进行优化;
在向左遍历过程中删去无用的数(左边小于,但值大于),利用栈形成单调增大的序列,所求数即为栈顶;
for(int i=0;i<n;i++){
scanf("%d",&v);
while(top&&s[top-1]>=v) top--; //去除比当前数大但在左边的数
if(!top) printf("-1 ");
else printf("%d ",s[top-1]); //输出栈顶元素,即第一个小于当前数的数
s[top++]=v; //当前数压入栈中
}
应用场景:滑动窗口中最小值,也可优化背包问题;
思路:同理通过删去无用的数进行优化;
(求滑动窗口中最小值)队列头保留最小的数,遍历数组,若队尾数大于遍历的数则不断删去队尾(同理无用的数),使得队列单调增,在遍历过程中,不断更新队头使得不超过滑动窗口。
for(int i=0;i<n;i++){
if(l<r&&i-q[l]>len-1) l++; //移动对头使不超过滑动窗口,为了实现,q数组存下标
while(l<r&&v[q[r-1]]>=v[i]) r--; //弹出队尾无用数,因为会在队尾弹出不满足先进先出原则,事实上也不能叫单调队列
q[r++]=i; //每次都入队一个
if(i>=len-1) printf("%d ",v[q[l]]);
}
(考研真题待更新)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。