第四章:栈与队列
栈(stack):限定仅在表尾进行插入和删除操作的线性表
队列:只允许在一端插入操作,在另一端进行删除操作的线性表
栈的定义:
- 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何元素的栈称为空栈,是一种**后进先出(Last In Fast Out,LIFO)**的线性表。
- 栈的插入操作(push):进栈、压栈或入栈
- 栈的删除操作(pop):出栈或弹栈
栈的顺序存储结构:
- 顺序栈,可用数组实现,将下标为0的一端作为栈底,存放首元素top = -1 时表示空栈
两栈共享空间:
- 当我们有两个类型相同的栈时,可将内存共享,数组两个端点分别为栈底bottom1=0,bottom2=n-1
![](https://i-blog.csdnimg.cn/blog_migrate/31c25dc4af7fcebd60e806638fe3cac2.png)
这样的共享栈结构,通常运用于两个栈空间需求有相反关系时。
栈的链式存储结构:
- 链栈,链式存储结构,由于单链表有头指针,栈顶指针也是必须的,所以选择单链表头部作为栈顶。
栈的应用——递归
斐波那契数列(Fibonacci)的实现:
def Fibonacci(i):
if i < 2: # 基线条件
return i
else: # 递归条件
return Fibonacci(i - 1) + Fibonacci(i - 2)
def main():
fibonacci_number = 12
for i in range(1, fibonacci_number + 1):
print(Fibonacci(i), end=' ')
if __name__ == '__main__':
main()
当然用循环迭代同样可实现斐波那契数列,递归则使代码更加干净,递归函数一定注意其基线条件,避免形成死循环。
栈的应用——四则运算表达式
- 后缀(逆波兰)表达式:一种不需要括号的后缀表达式,平时我们常见的都为中缀表达式,便于计算机内部实现四则运算。
队列的定义(Queue):
- 队列是一种**先进先出(First In First Out,FIFO)**的线性表
- 允许插入的一端称为:队尾,允许删除的一端称为:队头
顺序存储循环队列,队列头尾相接的顺序结构
- front 指针指向队头元素,rear指针指向队尾元素的下一个位置,当front等于rear时,队列为空队列(rear == front)
- 对于循环队列时:( rear +1 ) % QueueSize == front 时,队列满。
- 计算队列长度:( rear - front + QueueSize) & QueueSize
链式存储机构,应用线性表的单链表
- 将队列的头指针front指向链队列的头结点,对尾指针指向终端结点
用列表实现队列入队出队:
class Queue(object): # 创建队列类
def __init__(self):
self.queue_list = []
def is_empyt(self): # 判断队列是否为空
return self.queue_list == []
def en_queue(self, data): # 在队列尾部添加新元素——入队
self.queue_list.append(data)
def de_queue(self): # 队头元素出队,并返回其值
de_queue_value = self.queue_list.pop(0)
return de_queue_value
def size_queue(self): # 返回当前队列长度
return len(self.queue_list)
if __name__ == '__main__':
q = Queue()
print('当前队列长度:', q.size_queue())
q.en_queue(1)
q.en_queue(2)
q.en_queue(3)
print('入队三个元素后长度:', q.size_queue())
print('出队元素:', q.de_queue())