第四章 堆栈
1.线性表:包括顺序表(在连续的物理内存上存储一系列连续的数据)和链表(在非连续的内存上通过链接的形式存储一组连续的数据)。
2.堆栈:可以看做是一个存储数据的容器,一般不关心其物理存放方式(既可以采用顺序表存储,也可以采用链表存储),而是关注其支持的操作。它具有后进先出(原因:只能允许在容器的一端(称为栈顶端指标)进行加入数据和输出数据的运算)的特点。
3.堆栈支持的相关的数据操作有:Stack() 创建一个新的空栈(可以通过链表和顺序表创建,这里以列表实现。);push(item) 添加一个新的元素item到栈顶;pop() 弹出栈顶元素;peek() 返回栈顶元素;is_empty() 判断栈是否为空;size() 返回栈的元素个数。
# -*- coding:utf-8 -*-
class Stack():
def __init__(self):
self.__items=[]#不希望外部使用跳过封装方法,加私有
def push(self,item):
'''添加一个新的元素item到栈顶'''
self.__items.append(item)
def pop(self):
'''弹出栈顶元素,要保证添加的位置与弹出的位置一致'''
return self.__items.pop()
def peek(self):
'''返回栈顶元素,但不是从栈顶取出,要使得该元素仍在栈中'''
if not self.__items:
return
else:
return self.__items[-1]#注意:空列表不支持[-1]操作
def is_empty(self):
'''判断栈是否为空'''
return not self.__items
#对于布尔值,空对象代表False,非空对象代表True
def size(self):
'''返回栈的元素个数'''
return len(self.__items)
if __name__=='__main__':
stack = Stack()
stack.push("hello")
stack.push("world")
stack.push("itcast")
print(stack.size())
print(stack.peek())
print(stack.pop())
print(stack.pop())
print(stack.is_empty())
print(stack.pop())
print(stack.is_empty())
第五章 队列
1.队列(先进先出):队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表(即存储这种数据结构可以选择顺序表或者链表,这里选择列表),其中,允许入队(enqueue)或者添加的一端为队尾,允许删除或者出队(dequeue)的一端为队头。
2.普通队列支持的操作有:Queue() 创建一个空的队列;enqueue(item) 往队列中添加一个item元素;dequeue() 从队列头部删除一个元素;is_empty() 判断一个队列是否为空;size() 返回队列的大小。
# -*- coding:utf-8 -*-
class Queue():
def __init__(self):
self.queue=[]
def enqueue(self,item):
'''往队列中添加一个item元素'''
self.queue.append(item)
#self.queue.insert(0,item)
def dequeue(self):
'''从队列头部删除一个元素'''
return self.queue.pop(0)
# self.queue.pop()
def is_empty(self):
'''判断一个队列是否为空'''
return self.queue==[]
def size(self):
'''返回队列的大小'''
return len(self.queue)
if __name__ == "__main__":
q = Queue()
q.enqueue("hello")
q.enqueue("world")
q.enqueue("itcast")
print(q.size())
print(q.dequeue())
print(q.dequeue())
print(q.dequeue())
在上面的普通队列的实现代码中,对于往队尾添加,队头读取的操作有两种实现代码但要注意队列与栈不同,其队头与队尾对应列表的两端,则入队使用insert(0,item)时认为列表头部是队列尾部,则列表尾部对应队列头部,因此出队使用pop()。当然,若入队使用append(item)时,认为列表尾部是队列尾部,则列表头部对应队列头部,因此出队使用pop(0)。但是这两种代码都是出队和入队一个时间复杂度为O(n),一个为O(1),所以使用时根据操作的实际情况看出队还是入队次数多进行合适的选择。
3.双端队列:双端队列(deque),是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队(双端队列可以看做两个底部重合的栈的组合)。
其支持的操作有:Deque() 创建一个空的双端队列;add_front(item) 从队头加入一个item元素;add_rear(item) 从队尾加入一个item元素;remove_front() 从队头删除一个item元素;remove_rear() 从队尾删除一个item元素;is_empty() 判断双端队列是否为空;size() 返回队列的大小。实现代码如下:
# -*- coding:utf-8 -*-
class Deque() :
'''创建一个空的双端队列'''
def __init__(self):
self.deque=[]
def add_front(self,item) :
'''从队头加入一个item元素'''
self.deque.insert(0,item)
def add_rear(self,item) :
'''从队尾加入一个item元素'''
self.deque.append(item)
def remove_front(self) :
'''从队头删除一个item元素'''
return self.deque.pop(0)
def remove_rear(self):
'''从队尾删除一个item元素'''
return self.deque.pop()
def is_empty(self) :
'''判断双端队列是否为空'''
return not self.deque
def size(self) :
'''返回队列的大小'''
return len(self.deque)
if __name__ == "__main__":
deque = Deque()
deque.add_front(1)
deque.add_front(2)
deque.add_rear(3)
deque.add_rear(4)
print(deque.size())
print(deque.remove_front())
print(deque.remove_front())
print(deque.remove_rear())
print(deque.remove_rear())