一、
栈的操作特性:栈是一种“操作受限”的线性表,只允许在一端插入和删除数据
从功能上来说,链表确实可以替代栈,但是数组或链表暴露了太多的操作接口,操作上的确灵活自由,但使用时就比较不可控,更容易出错。
当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出、先进后出的特性,我们就应该首选“栈”这种数据结构。
栈主要包含两个操作,入栈和出栈,也就是在栈顶插入一个数据和从栈顶删除一个数据。
栈既可以用顺序表来实现,也可以用链表来实现。用顺序表实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。
栈的方法实现:
# -*- encoding: utf-8 -*-
"""
@File : _stack.py
@Time : 2019/11/17 16:07
@Author : chen
"""
'''栈的实现'''
class Stack(object):
'''列表实现栈'''
def __init__(self):
self.__item = [] # 空列表 __item是为了区分后面的item
def is_empty(self):
# 判空
# return self.__item == []
if self.__item == []:
return True
else:
return False
# 添加元素
def push(self,item):
'''
:param item:添加新元素到栈顶
:return:
'''
self.__item.append(item)
# 弹出栈顶元素
def pop(self):
self.__item.pop() # 列表的尾部就是栈顶
# 返回栈顶元素
def peek(self):
if self.is_empty():
return None
else:
return self.__item[-1]
# return self.__item[len(self.__item) - 1] # 另一种表达方法
# 返回栈的元素个数
def size(self):
return len(self.__item)
# 遍历所有元素
def travel(self):
print(self.__item)
for item in self.__item:
print(item)
if __name__ == '__main__':
s = Stack()
print(s.is_empty())
s.push(1)
s.push(2)
s.push(3)
s.pop()
s.peek()
print(s.size())
print(s.is_empty())
s.travel()
二、
队列:先进者先出,这就是典型的“队列”
队列跟栈一样,也是一种操作受限的线性表数据结构。
作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列、阻塞队列、并发队列。它们在很多偏底层系统、框架、中间件的开发中,起着关键作用。
# -*- encoding: utf-8 -*-
"""
@File : _queue.py
@Time : 2019/11/17 20:17
@Author : chen
"""
'''队列的实现'''
# 用列表实现
class Queue(object):
def __init__(self):
self.__items = [] # 空队列
# 入队
def enqueue(self, item):
'''
:param item:队列中添加一个元素
:return:
'''
self.__items.append(item)
# 出队
def dequeue(self):
'''
:return:队列头元素
'''
return self.__items.pop(0) # pop函数默认是删除最后一个元素,加上索引0代表队列头部第一个元素
# 判空 返回True或者False
def is_empty(self):
return self.__items == []
# 长度
def size(self):
return len(self.__items)
def travel(self):
"""
遍历元素
:return:
"""
for item in self.__items:
print(item)
if __name__ == '__main__':
q = Queue()
print(q.is_empty())
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
q.enqueue(4)
print(q.is_empty())
print(q.size())
q.travel()
q.dequeue()
q.dequeue()
q.travel()
三、
双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。
双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
# -*- encoding: utf-8 -*-
"""
@File : double_queue.py
@Time : 2019/11/17 20:48
@Author : chen
"""
# 双端队列
class Dequeue(object):
def __init__(self):
self.__items = []
def is_empty(self):
return self.__items == [] # 这里和上面初始化不同
def size(self):
return len(self.__items)
def travel(self):
for item in self.__items:
print(item)
# 队尾添加元素
def add_rear(self, item):
return self.__items.append(item)
# 队头添加元素
def add_front(self, item):
return self.__items.insert(0, item)
# 队头删除一个元素
def remove_front(self):
return self.__items.pop(0)
# 队尾删除一个元素
def remove_rear(self):
return self.__items.pop() # pop函数本身就是删除列表尾部数据
if __name__ == '__main__': # 这个语句的意思就是当这个py文件是主文件的时候,执行下面的操作,多用于项目中多个py文件时候区分主py文件
d = Dequeue()
print(d.is_empty())
d.add_front(1)
d.add_rear(2)
d.add_front(0)
d.add_rear(5)
d.travel()
d.remove_front()
d.remove_rear()
d.travel()
四、
阻塞队列 input函数就是阻塞队列 print函数就是非阻塞队列
阻塞队列其实就是在队列基础上增加了阻塞操作。简单来说,就是在队列为空的时候,从队头取数据会被阻塞。因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后再返回。