第3章栈、队列、数组和矩阵

文章目录

    • 考纲和命题形式
      • 考纲
      • 命题形式
      • 基本概念
      • 栈的基本操作
      • 栈的两种存储方式
        • 顺序栈
        • 代码
        • 共享栈
        • 链栈
        • 代码
    • 队列
      • 队列的基本概念
      • 队列的顺序存储结构
        • 循环队列
      • 队列的链式存储结构
      • 双端队列
    • 错题
      • 队列

今日格言:有很多时候,勇气不是从你的脑袋里生出,而是从你的脚下涌现。

考纲和命题形式

考纲

  1. 栈和队列的基本概念
  2. 栈和队列的顺序存储结构
  3. 栈和队列的链式存储结构
  4. 多维数组的存储
  5. 特殊矩阵的压缩存储
  6. 栈、队列和数组的应用

命题形式

  • 通常以选择题1至2题考察4个考点
  • 大题中只有19年考了一个队列
    题目不算难,但命题的形式比较灵活,其中栈(出入栈的过程、出栈序列的合法性和种类)以及其特征是重点。

基本概念

🌟栈的定义:栈(Stack)是只允许在一端进行插入或删除操作线性表 。也就是说栈是一种受限线性表,限定这种线性表只能在某一端进行插入和删除操作。这是从数据的逻辑结构上了解栈。

如上图所示:不含任何元素的栈叫做空栈 也是空表。

🌟栈顶 (Top)是栈(线性表)允许进行插入和删除的那一端。

🌟栈底 (Bottom)是固定的,不允许进行插入和删除的另外一端。

可以将其形象地记忆为垒起来的石堆(stack)或者一摞只允许从上面放下或者拿走的一摞盘子。

另外,从图中可以看出a1a_1a1是栈底元素,a4a_4a4是栈顶元素,a1a_1a1虽然最先从栈顶入栈,但是要想出栈必须在a4a_4a4出栈之后,这就是栈的操作特性:后进先出即Last in First out(LIFO)。

下面这段简单的模拟栈的C语言程序有助于理解:

c 复制代码
#include<stdio.h>
int main(){    

int Stack[5];    
int top = -1;  //模拟栈顶指针    
int bottom = 0;        

Stack[++top]=985;//模拟入栈    
Stack[++top]=211;    
Stack[++top]=400;        

while(top >= bottom) { //按序打印栈中内容        
    printf("当前栈顶元素为:%d\n",Stack[top]);// 打印当前栈顶元素        
    top--; // 出栈    
}        
    return 0;
}    

栈的基本操作

接下来从数据的运算角度来看栈---栈的基本操作。除了上面提到的进栈、出栈操作,栈还有以下基本操作:

  • 创: InitStack(&S):初始化一个空栈S。
  • 销:DestroyStack(&S):销毁栈,并释放栈S占用的存储空间(顺序栈使用静态数组存储元素,只需逻辑上删除所有元素即可,存储空间系统自动回收)。
  • 查:GetTop(S,&x):若栈S非空,则读取栈顶元素,并不出栈;若栈为空则报错。
  • 判空:StackEmpty(S):判空操作,若S为空栈,则返回true否则返回false。
    入栈和出栈的操作如下:
  • 增:Push(&S,x):若栈未满则进栈,使x成为新栈顶,若栈满则报错。
  • 删:Pop(&S,&x):出栈,若栈非空,则弹出栈顶元素并用x返回;若栈空则报错。
    一个小知识点:当n个不同元素进栈时,出栈元素不同排列的个数为:

    这个数也叫做卡特兰数。

栈的两种存储方式

接下来我们将从数据的存储结构上来了解栈,栈也采用之前线性表使用的两种存储结构---顺序存储和链式存储。至于索引存储,我只在操作系统和计算机组成原理的存储系统这一章里看到过,而散列存储似乎和查找这一章节有关。

顺序栈

🌟采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针top指示当前栈顶元素的位置。 (真正有效的文字就应该这样,简短而富含信息,值得学习)一组连续的存储单元在这里就是指静态数组

代码

示例代码仅供参考,更严谨代码请动手写代码并且运行。

1.顺序栈的定义

c 复制代码
#include <stdio.h>
#define MaxSize 10
typedef struct {
ElemType data[Maxsize];
int top;
}SqStack;	//Sequence Stack 顺序栈

建议写代码的时候脑子里也要想着内存图:

  1. 顺序栈的基本操作
c 复制代码
//初始化 
void InitStack(SqStack &S) {
	S.top = -1;    //初始化栈顶指针 
}
//判栈空
bool StackEmpty(SqStack S) {
	if(S.top == -1)
		return true;
	else
	    return false;
} 
//进栈
bool Push(SqStack &S,ElemType x) {
	if(S.top == MaxSize - 1)
		return false;	//栈满报错
	S.data[++S.top] = x;
	return true; 
} 
//出栈
bool Pop(SqStack &S,ElemType &x) {
	if(S.top == -1)
		return false;    //栈空报错
	x = S.data[S.top--];
	return true;
} 
//读栈顶元素
bool GetTop(SqStack S,ElemType &x) {
	if(S.top == -1)
		return false;    //栈空报错
	x = S.data[S.top];   //x记录栈顶元素
	return true; 
} 

另一种方法是令top为0,这就会带来入栈操作、出栈操作、判空操作和判满操作的变化:

c 复制代码
S.data[top++]=x;//进栈
x=S.data[--top];//出栈
if(S.top == 0) //判空
if(S.top == MaxSize)  //判满
  1. 使用顺序栈实现第一个模拟栈的程序
c 复制代码
int main() {
	ElemType x;
	SqStack S;
	InitStack(S);
	Push(S,985);
	Push(S,211);
	Push(S,400);
	while(!StackEmpty(S)) {
		Pop(S,x); //获取栈顶元素并出栈
		printf("当前栈顶元素为%d\n",x); 
	}
	return 0;
} 
共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸,如下图所示:

两个栈的栈顶指针都指向栈顶元素,top0=-1时0号栈为空,top1=MaxSize时1号栈为空;仅当两个栈顶指针相邻(top1-top0=1)时,判断栈满。当0号栈进栈时top0先加上1再赋值,1号栈进栈时top1先减1再赋值,出栈时顺序正好相反。

共享栈是为了更有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才发生上溢。其存取数据的时间复杂度均为O(1),所以对存取效率没有什么影响。

定义及初始化代码如下:

c 复制代码
#define MaxSize 10
typedef struct{
ElemType data[MaxSize];
int top0;  //0号栈栈顶指针
int top1;  //1号栈栈顶指针
}ShStack;
void InitStack(ShStack &S) {
S.top0 = -1;
S.top1 = MaxSize;
}
链栈

🌟定义:采用链式存储的栈就是链栈。

优点:便于多个栈共享存储空间和提高其效率,且不存在栈满上溢 的情况。通常采用单链表 实现,并规定入栈和出栈操作是在单链表的表头 进行的。采用链式存储,便于结点的插入与删除。链栈的操作与链表类似,入栈和出栈的操作都在链表的表头 进行。需要注意的是:对于带头结点和不带头结点的链栈,具体的实现会有所不同

链栈本质上还是一个单链表 ,只不过是把表头的那端当作栈顶 。入栈操作对应单链表的头插法 ,出栈操作对应头结点的后删操作

下面这个过程图是使用带头结点的链栈 实现第一个模拟栈的C语言程序:


代码

1.带头结点的链栈(c++)

c++ 复制代码
/带头结点的链栈
typedef int ElemType;    //定义元素类型为int类型
typedef struct LinkNode{
ElemType data;    //数据域
struct LinkNode *next;    //指针域
}LinkStack, *Lhead;
//初始化
void InitStack(Lhead &L) {   
L=(LinkStack *)malloc(sizeof(LinkStack));   
L->next = NULL;
}
//判栈空
bool StackEmpty(Lhead L){    
if(L->next == NULL)        
return true;    //栈空    
else        
return false;    
}
//进栈
bool Push(Lhead &L,ElemType x){    
LinkStack *p = (LinkStack *)malloc(sizeof(LinkStack));    
if(p==NULL)        
return false;//申请空间失败    
p->data = x;    
p->next = L->next;    
L->next = p;    
return true;    }
//出栈bool Pop(Lhead &L,ElemType &x) {    
if(StackEmpty(L))        
return false;    //栈空    
LinkStack *p = L->next;    //找到栈顶结点    
x = p->data;    //获取栈顶元素    
L->next = p->next;    //出栈    
free(p);    //释放结点空间    
return true;
}
int main()    {
//用链栈表示第一个模拟栈程序    
ElemType x;    
Lhead L;    //创建一个链栈并初始化    
InitStack(L);    
Push(L,985);    
Push(L,211);    
Push(L,400);    
//按序打印栈中元素    
while(!StackEmpty(L)){        
Pop(L,x);    //获取栈顶元素并出栈        
printf("当前栈顶元素为:%d\n",x);    
}    
Pop(L,x);    
return 0;
}

2.不带头结点的链栈

队列

仍然从逻辑结构、基本运算、存储结构这三个方面了解队列

队列的基本概念

1.队列的定义
队列(Queue)和栈一样也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除 。允许删除的一端称为队头(Front) ,又称队首。允许插入的一端称为队尾(Rear) 。向队列中插入元素称为入队或进队;删除元素称为出队或离队。这和日常生活中的排队是一致的,最早排队的也是最早离队的,其操作特性是先进先出(FIFO)。

2.队列常见的基本操作

  • 创:
  • 销:
  • 增:
  • 删:
  • 查:
  • 判队空:
  • 读队头:

队列的顺序存储结构

队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针(front)和队尾指针(rear)。

队列的顺序存储类型可描述为:

c 复制代码
#define MaxSize 50    //定义队列中元素的最大个数
typedef struct{
    ElemType data[MaxSize];
    int rear,front;
}SqQueue;
循环队列

队列的链式存储结构

队列的链式表示称为链队列,它实际上是一个同时有队头指针和队尾指针的单链表,如下图所示:

双端队列

双端队列是指允许两端都可以进行插入和删除操作的线性表,如下图所示:

1小时看45min视频,1小时整理基础知识,1小时做选择题,0.5小时敲代码,0.5小时处理错题。

错题

第一次做对了,但第二次做错了,根本原因就是用的是举特例,第一次列出来了,第二次列出来少了一个,本质上还是不会,应该使用讨论的方法,真正做对。

队列

相关推荐
Always_away4 小时前
26考研|数学分析:重积分
笔记·学习·考研·数学
图灵学术计算机论文辅导1 天前
提示+掩膜+注意力=Mamba三连击,跨模态任务全面超越
论文阅读·人工智能·经验分享·科技·深度学习·考研·计算机视觉
图先2 天前
高数常用公式与不等式
考研
图灵学术计算机论文辅导3 天前
1+1>2!特征融合如何让目标检测更懂 “场景”?
论文阅读·人工智能·经验分享·考研·机器学习·计算机视觉·目标跟踪
Fengshana3 天前
王道考研-数据结构-01
数据结构·考研
滋滋不吱吱5 天前
枚举中间位置基础篇
考研·算法·leetcode
图灵学术计算机论文辅导5 天前
特征融合+目标检测!3篇CVPR新作把多模态目标检测拉高10个mAP
论文阅读·人工智能·考研·机器学习·计算机视觉·目标跟踪·信息与通信
缘友一世6 天前
操作系统PV专题题型突破(考研版)
考研·操作系统·pv·os
以梦为马mmky6 天前
考研初试专业分146!上岸新疆大学!信号与系统考研经验,通信考研小马哥。
考研·通信考研小马哥·通信考研·信号与系统·考研经验·新疆大学