栈和队列都是特殊的线性表,对插入删除有限制。 栈 先进后出 在表尾进行插入和删除;队列 先进先出 在表尾进行插入,表头进行删除。
图的拓扑排序 深度优先 关键路径算法用的辅助数据结构是栈
树的层序遍历 图的广度优先遍历用的数据结构是队列
1、栈
1.1、栈的定义
顺序存储是分配一组连续的存储单元 ,如果栈满,不能再添加;采用链式存储,可以需要多少存储空间就申请多少空间。
1.2、栈的实现方式
1.2.1、顺序存储方式
class Stack:
"栈"
def __init__(self):
self.stack = []
def push(self,item):
"添加一个新元素item到栈顶"
self.stack.append(item)
def pop(self):
"弹出栈顶元素"
return self.stack.pop()
def peek(self):
"返回栈顶元素"
if self.stack:
return self.stack[-1]
else:
return None
def is_empty(self):
"判断栈是否为空"
return self.stack
def size(self):
"返回栈的元素个数"
return len(self.stack)
if __name__ == "__main__":
s = Stack()
s.push(1)
s.push(2)
print(s.pop())
1.2.2、链式存储方式
class StackNode:
def __init__(self):
self.data = None
self.next = None
class LinkStack:
def __init__(self):
self.top = StackNode()
'''判断链栈是否为空'''
def IsEmptyStack(self):
if self.top.next == None:
iTop = True
else:
iTop = False
return iTop
'''进栈'''
def PushStack(self,da):
tStackNode = StackNode()
tStackNode.data = da
tStackNode.next = self.top.next
self.top.next = tStackNode
print("当前入栈的元素为:",da)
'''出栈'''
def PopStack(self):
if self.IsEmptyStack() == True:
return
else:
tStackNode = self.top.next
self.top.next = tStackNode.next
return tStackNode.data
'''获取栈顶元素'''
def GetTopStack(self):
if self.IsEmptyStack() == True:
print("栈为空")
else:
return self.top.next.data
'''创建一个链栈'''
def CreateStackByInput(self):
data = input("请输入元素(确定按回车键,结束按“#”):")
while data != "#":
self.PushStack(data)
data = input("请输入元素(确定按回车键,结束按“#”):")
def StackVisit(self):
element = input("请输入要寻找的元素:")
i = 0
tStackNode = self.top
result = self.PopStack()
while tStackNode.next!= None and element != result:
tStackNode = tStackNode.next
result = self.PopStack()
i += 1
if element == result:
print("已找到,距栈顶",i,"个位置")
else:
print("链栈中无此元素")
Ls = LinkStack()
Ls.CreateStackByInput()
Ls.StackVisit()
2、队列
队列的头部和位可以自己规定,但是一旦规定好,定义的头部和尾部操作就不能随便改变。
在头部添加,应该在尾部删除;在尾部添加,应该在头部删除元素,自己定义队列的头部和尾部。
2.1、顺序表的队列实现
class Queue(object):
"队列"
def __init__(self):
self._list = []
def enqueue(self,item):
"往队列尾部中添加一个新元素item"
self._list.append(item)
def dequeue(self):
"从队列头部删除一个元素"
return self._list.pop(0)
"在队列的尾部删除元素"
def is_empty(self):
"判断队列是否为空"
return self._list == []
def size(self):
"返回队列的大小"
return len(self._list)
if __name__ == "__main__":
s = Queue()
s.enqueue(1)
s.enqueue(2)
print(s.dequeue())
2.2、链表的队列实现
2.3、双端队列
基于顺序表的双端队列实现
class Queue(object):
"双端队列"
def __init__(self):
self._list = []
def add_front(self,item):
"在队列的头部添加一个元素"
self._list.insert(0,item)
def add_rear(self,item):
"往队列尾部中添加一个新元素item"
self._list.append(item)
def pop_front(self):
"从队列头部取出一个元素"
return self._list.pop(0)
def pop_rear(self):
"从队列尾部取出一个元素"
return self._list.pop()
def is_empty(self):
"判断队列是否为空"
return self._list == []
def size(self):
"返回队列的大小"
return len(self._list)
if __name__ == "__main__":
s = Queue()
s.add_front(1)
s.add_front(2)
print(s.pop_front())
2.4、循环队列的计算问题
关于循环队列的一些计算问题:
front为队头、rear为队尾元素的下一个位置、maxSize为队列的总容量、m为队列中元素的个数:
队空:front = rear
队满:(rear + 1) % maxSize = front
进队:front = (front + 1) % maxSize
出队:rear = (rear + 1) % maxSize
队列中元素的个数 m = (rear - front + maxSize) % maxSize