第三章 盏、队列和数组

本文深入介绍了栈和队列这两种基本数据结构,包括它们的概念、链式和顺序存储结构的实现,以及在括号匹配、表达式求值等场景中的应用。此外,还涉及了双端队列的特性。通过实例代码展示了如何操作栈和队列,并探讨了它们在计算机系统中的作用。
摘要由CSDN通过智能技术生成


前言

本文主要介绍栈、队列和数组。


一、栈

1.栈的基本概念

栈:只容许在一端进行插入或删除的线性表。
栈顶:线性允许进行插入删除的那一端。
栈底:固定的、不允许进行插入与删除的另一端。在这里插入图片描述

2.栈的基本操作

A.常用操作

定义栈、初始化栈、判空栈、入栈、出栈、读栈。

B. 实战代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
 
#define MaxSize 50
typedef int ElempType;

//0 栈的定义
typedef struct {
	ElempType data[50];
	int top;
}SqStack;
//1 初始化
void InistStack(SqStack& S)
{
	S.top = -1;//代表栈为空
}
//2 栈判空
bool StackEmpty(SqStack S)
{
	if (S.top == -1)
		return true;
	else
		return false;
 }
//3 入栈
bool Push(SqStack &S, ElempType x)
{
	if (S.top == MaxSize - 1)//栈满,报错
		return false;
	S.data[++S.top] = x;//指针先加1,再入栈
	return true;
}

//4 出栈
bool Pop(SqStack &S, ElempType &x)
{
	if (S.top ==  - 1)//栈空,报错
		return false;
	 x=S.data[S.top--];//先出栈,指针再减1
	 return true;
}

//5 读栈
bool GetTop(SqStack S, ElempType& x)
{
	if (S.top == -1)//栈空,报错
		return false;
	x = S.data[S.top];//x记录栈元素
	return true;
}

int main()
{
	//0-定义栈
	SqStack S;//定义栈,先进后出 FILEO LIFO

	//1-初始化
	InistStack(S);//初始化
	//2-判空栈
	bool flag;
	flag = StackEmpty;
	if (flag)
	{
		printf("栈是空的\n");
	}
	//3-入栈
	Push(S, 3);//入栈元素3
	Push(S, 4);//入栈元素4
	Push(S, 5);//入栈元素5
	//4-出栈
	ElempType m;//用来存放拿出的元素
	Pop(S, m);
	//5-读栈
	GetTop(S, m);//获取栈顶元素
	printf("栈顶元素为%d\n", m);
}

3.栈的链式存储

核心代码

typedef struct Linknode{
    ElemType data;
    struct Linknode *next;
    }*LiStack;

二、队列

1.队列的基本概念

队列:一种操作受限制的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。
入队(进队):向队列中插入元素。
出队(离队):删除列表中的元素。
队头(Front):允许删除的一端。
队尾(Front):允许插入的一端。
特点:先进先出(First In First Out,FIFO)
在这里插入图片描述

2.队列的顺序存储结构

A.队列的顺序存储

定义:

//伪代码,队列的定义
#define MaxSize 50
typedef int ElempType;
typedef struct {
	ElempType data[MaxSize];//存放队列元素
	int front, rear;//队头指针与队尾指针
} SqQueue;

B.循环队列

含义:将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环。
在这里插入图片描述
1

C.循环队列的操作

C.1 初始化
void InitQueue(SqQueue& Q) {
	Q.rear = Q.front = 0;
}
C.2 判队空
bool isEmpty(SqQueue Q) {
	if (Q.rear == Q.front) return true;//队空条件
	else                   return false;
}
C.3 入队
bool EnQueue(SqQueue& Q, ElempType x) {
	if((Q.rear+1)%MaxSize == Q.front) //队满报错
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;//队尾指针加1取模
	return true;
}
C.4 出队
bool DeQueue(SqQueue& Q, ElempType x) {
	if (Q.rear == Q.front) //队空报错
		return false;
	x=Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;//队头指针加1取模
	return true;
}
D 实战代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 50
typedef int ElempType;
//0 定义
typedef struct {
	ElempType data[MaxSize];//存放队列元素
	int front, rear;//队头指针与队尾指针
} SqQueue;

//1 初始化
void InitQueue(SqQueue& Q) {
	Q.rear = Q.front = 0;
}

//2 判断空
bool isEmpty(SqQueue Q) {
	if (Q.rear == Q.front) return true;//队空条件
	else                   return false;
}
//3 入队
bool EnQueue(SqQueue& Q, ElempType x) {
	if((Q.rear+1)%MaxSize == Q.front) //队满报错
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;//队尾指针加1取模
	return true;
}
//4 出队
bool DeQueue(SqQueue& Q, ElempType x) {
	if (Q.rear == Q.front) //队空报错
		return false;
	x=Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;//队头指针加1取模
	return true;
}

int main(){
	//0-定义
	SqQueue Q;
	//1-初始化
	InitQueue(Q);
	//2-判空
	bool ret_1 = isEmpty(Q);
	if (ret_1)
		printf("队列为空\n");
	else
		printf("队列不为空\n");
	//3-入队
	EnQueue(Q, 4);
	EnQueue(Q, 3); 
	bool ret_2 = EnQueue(Q, 2);
	if (ret_2)
		printf("入队成功\n");
	else
		printf("入队失败\n");
	//4-出队
	int x=0;
	bool ret_3 = DeQueue(Q, x);
	if (ret_3)
		printf("出队成功\n",);
	else
		printf("出队失败\n");
}

3.队列的链式存储结构

A. 队列的链式存储

含义:队列的链式表示称为链队列,它是一个同时带有队头指针与队尾指针的单链表。
在这里插入图片描述
队列链的描述:

typedef struct {         // 链式队列结点
	ElempType data;
	struct LinkNode* next;
} LinkNode;
typedef struct {         //链式队列
	ElempType data;
	LinkNode* front,*rear;  //队列的队头指针与队尾指针
} LinkQueue;

B. 链式队列的基本操作

B.1 初始化
void InitQueue(LinkQueue& Q) {
	Q.rear = Q.front = (LinkNode*)malloc(sizeof(LinkNode));//建立头结点
	Q.front->next = NULL;//初始为空
}
B.2 判断空
bool IsEmpty(LinkQueue Q) {
	if (Q.rear == Q.front) return true;//队空条件
	else                   return false;
}
B.3 入队
void EnQueue(LinkQueue& Q, ElempType x) {
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x; s->data = NULL;//创建新节点,插入到链尾
	Q.rear->next = s;
	Q.rear = s;
}
B.4 出队
bool DeQueue(LinkQueue &Q, ElempType x) {
	if (Q.rear == Q.front)  return false;//队空报错
	LinkNode *p = Q.front->next;
	x = p->data;
	Q.front->next = p->next;
	if (Q.rear == p) Q.rear = Q.front;//若原队列中只有一个节点,删除后变空
	free(p);
	return true;
}
C实战代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 50
typedef int ElempType;
//0定义
typedef struct {         // 链式队列结点
	ElempType data;
	struct LinkNode *next;
} LinkNode;
typedef struct {         //链式队列
	ElempType data;
	LinkNode* front, * rear;  //队列的队头指针与队尾指针
} LinkQueue;
//1 初始化
void InitQueue(LinkQueue & Q) {
	Q.rear = Q.front = (LinkNode*)malloc(sizeof(LinkNode));//建立头结点
	Q.front->next = NULL;//初始为空
}
//2 判断空

bool IsEmpty(LinkQueue Q) {
	if (Q.rear == Q.front) return true;//队空条件
	else                   return false;
}
//3 入队
void EnQueue(LinkQueue &Q, ElempType x) {
	LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x; s->data = NULL;//创建新节点,插入到链尾
	(Q.rear)->next = s;
	Q.rear = s;
}
//4 出队
bool DeQueue(LinkQueue & Q, ElempType x) {
	if (Q.rear == Q.front)  return false;//队空报错
	LinkNode* p = Q.front->next;
	x = p->data;
	Q.front->next = p->next;
	if (Q.rear == p) Q.rear = Q.front;//若原队列中只有一个节点,删除后变空
	free(p);
	return true;
}
int main() {
	//0-定义
	LinkQueue Q;
	//1-初始化
	InitQueue(Q);
	//2-判空
	bool ret_1 = IsEmpty(Q);
	if (ret_1)
		printf("队列为空\n");
	else
		printf("队列不为空\n");
	//3-入队
	EnQueue(Q, 4);
	EnQueue(Q, 3);
	//4-出队
	ElempType x;
	bool ret_3 = DeQueue(Q, x);
	if (ret_3)
		printf("出队成功,出队元素为%d\n",x);
	else
		printf("出队失败\n");
}

4. 双端队列

A. 含义

允许两端都可以进行入队与出队操作的队列。
在这里插入图片描述

B. 输出受限的双端队列

允许在一端进行插入与删除,而在另一端只允许插入的双端队列称为输出受限的双端队列。

C. 输入受限的双端队列

允许在一端进行插入与删除,而在另一端只允许删除的双端队列称为输出受限的双端队列。

三、栈和队列的应用

1. 栈在括号匹配中的应用

先进的左括号等待后进的右括号匹配。

2. 栈在表达式求值中的应用

3. 栈在递归中的应用

//斐波拉契数列
int Fib(int n){
	if (n == 0)
		return 0;
	else if (n == 1)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main()
{
	printf("一次上1-2台阶,一共有%d种走法\n", Fib(10));
}

4. 栈在层次遍历中的应用

5. 栈在计算机系统中的应用

速度匹配:缓冲器;
资源竞争:分时使用;

四、数组和特殊矩阵

1. 数组的定义

由n(n>=1)个相同类型的数据元素构成的有限序列。

2. 数组的存储结构

3. 矩阵的压缩存储结构

压缩存储:为多个值相同的元素只分配一个存储空间,对零元素不发分配存储空间。

A. 对称矩阵

B. 三角矩阵

C. 三对角矩阵

D. 稀疏矩阵


总结

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值