栈和队列
1.栈和队列的定义和特点
- 栈的定义和特点
- 队列的定义和特点
2.栈的表示和操作的实现
- 顺序栈的表示和实现
- 链栈的表示和实现
3.栈与递归
- 采用递归算法解决的问题
4队列的表示和操作的实现
- 循环队列-队列的顺序的表示和实现
- 链队列-队列的链式表示和实现
1.1栈的定义和特点
🔵栈:是限定仅在表尾进行插入或删除操作的线性表。
表尾端称为栈顶,表头端称为栈底
特点:后进先出(从表尾进入,从表尾出去)
1.2队列的定义和特点
🔵队列:是从队尾插入,队头删除的线性表
特点:先进先出(从队尾进入,从队头出去)
2.1顺序栈的表示和实现
指利用顺序存储结构实现的栈(利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素)
一般来说另设指针(base)指示栈底元素在顺序栈的位置。设指针(top)指示栈顶元素在顺序栈的位置
注意:
1.当base=top表示空栈
2.栈非空时,top始终指向栈顶元素的上一个位置()
2.1.1初始化
(动态分配一个预定义大小的数组空间)
设base指向该空间的基地址(栈底)且top=base=NULL
2.1.2入栈(插入)
判断栈是否满了,若满了返回ERROR
在栈顶插入新的元素
2.1.3出栈(删除)
判断栈是否为空,若空返回ERROR
指将栈顶的元素删除
2.1.4取栈顶元素
当栈非空时,返回当前栈顶元素的值,栈顶指针(top)保持不变。
2.2链栈的表示和实现
指用链式存储结构实现的栈(通常使用单链表来表示)
🔴栈的主要操作是在栈顶插入和删除,所以不需要设头节点。
2.2.1初始化
直接构造一个空栈,将栈顶指针置空
2.2.2入栈(插入)
与顺序栈入栈操作不同,链栈在入栈前不需要判断栈是否满了,只需要分配一个新的节点空间
分配一个新节点并赋值,然后插入栈顶并修改栈顶指针(top)+1
2.2.3出栈(删除)
判断栈是否为空,若空返回ERROR,
将栈顶元素赋给e,
用一个新指针临时保留栈顶元素的空间,以备释放,
修改栈顶指针,指向新的栈顶元素,
释放原栈顶元素的空间
2.2.4取栈顶元素
与顺序栈一样,当栈非空时,返回当前栈顶元素的值,栈顶指针(top)保持不变
3.1采用递归算法解决的问题
3.1.1阶乘函数
#include<stdio.h>
int FIN(int n)
{
if(n>=1)
return n*FIN(n-1);
}
int main()
{
int num = 0;
scanf_s("%d", &num);
printf("%d",FIN(num));
return 0;
}
3.1.2斐波那契数列
#include<stdio.h>
int FIN(int n)
{
if (n == 1 || n == 2)
return 1;
else
{
return FIN(n - 2) + FIN(n - 1);
}
}
int main()
{
int num = 0;
scanf_s("%d", &num);
printf("%d", FIN(num));
return 0;
}
🔴分治算法:将一个难以直接的大问题,分割成多个较小的相同问题。
注意:
递归是一种方法
分治是一种思想
分治可以用递归来实现,也可以不用递归
4.1循环队列-队列的顺序的表示和实现
🔴由于队列可能会出现“假溢出”,这是由于“队尾入队,队头出队”这种限制的操作造成的,
为了解决这种方法,可以将顺序队列变成一个环形的空间,称这种队列为循环队列
4.1.1初始化
动态分配一个预定义大小的数组空间
设base指向该数组空间的首地址
将头指针和尾指针置为0
4.1.2入队(插入)
判断队列是否为满,若满则返回ERROR
将新元素插入队尾
队尾指针+1
4.1.3出队(删除)
判断队列是否为空,若空则返回ERROR
保存队头元素
队头指针+1
4.1.4取队头元素
当队列非空时,返回当前队头元素的值,队头指针保存不变
4.2链队列-队列的链式表示和实现
指采用链式储存结构实现的队列
🔴为了操作方便,给链队列添加一个头节点,并令指针始终指向头节点
(头指针的指针域指向队头)
4.2.1初始化
构造一个只有一个头节点的空队,将头节点指针域置空
4.2.2入队(插入)
(和循环列队不同,链队列入队前不需要判断队是否满了,只需要为入队元素动态分配一个节点空间)
为入队元素分配节点空间并赋值,用指针p指向
将新节点插入到队尾
修改队尾指针p
4.2.3出队(删除)
判断队列是否为空,若空则返回ERROR
临时保存队头元素的值,以释放空间
修改头节点的指针域,指向下一个节点
判断出队元素是否为最后一个元素,若是,则将队尾指针指向头节点