链表实现的队列,除了__str__,__add__,__eq__方法的时间复杂度是O(n),pop()和add方法复杂度是O(1)。并且有头结点和尾节点住指针分别指向头部和尾部,可以以常数O(1)时间访问。总的空间大小是2n+3,每个节点都有数据和指向下个节点的指针,还有三个单元格存储队列的逻辑大小、头指针和尾指针。
数组实现的队列,如果数组大小不发生变化,除了__str__,__add__,__eq__外所有方法,最大的运行时间都是O(1), 并且用循环数组实现的队列,pop和add不会移动数组。当数组大小发生变化时,add和pop的时间复杂度都是O(n)
#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/3 6:28
file: arraystack.py
'''
class Array(object):
def __init__(self, capacity, fillValue = None):
self._items = list()
for item in range(capacity):
self._items.append(fillValue)
def __iter__(self):
return iter(self._items)
def __len__(self):
return len(self._items)
def __str__(self):
return str(self._items)
def __getitem__(self, index):
return self._items[index]
def __setitem__(self, index, newItem):
self._items[index] = newItem
class Node(object):
def __init__(self, data, next):
self.data = data
self.next = next
def __iter__(self):
cursor = self
while cursor != None:
yield cursor.data
cursor = cursor.next
class AbstractCollection(object):
def __init__(self, sourceCollection):
self._size = 0
if sourceCollection:
for item in sourceCollection:
self.add(item)
def isEmpty(self):
return len(self) == 0
def __add__(self, other):
result = type(self)(self)
for item in other:
result.add(item) # add方法在type(self)中一定要实现
return result
def __len__(self):
return self._size
def __str__(self):
return str(self)
def __eq__(self, other):
if self is other: return True
if type(self) != type(other) or\
len(self) != len(other):
return False
otherItem = iter(other) # iter为内置函数
for item in self:
if item != next(otherItem):
return False
return True
class LinkedQueue(AbstractCollection):
def __init__(self, souceCollenction=None):
self._front = None
self._rear = None
AbstractCollection.__init__(self, souceCollenction)
def __iter__(self):
def visitNode(node):
if not node is None:
visitNode(node.next)
temp.append(node.data)
temp = list()
visitNode(self._items)
return iter(temp)
def __str__(self):
return "{" + ' ,'.join(map(str, iter(self))) + "}"
def clear(self):
self._size = 0
def add(self, item):
newNode = Node(item, None)
if self.isEmpty():
self._front = newNode
else:
self._rear.next = newNode
self._rear = newNode
self._size += 1
def pop(self):
oldItem = self._front.data
self._front = self._front.next
self._size -= 1
if self._front == None:
self._rear = None
return oldItem
class ArrayQueue(AbstractCollection):
def __init__(self, sourceCollection=None):
self._front = None
self._rear = None
self._items = list()
AbstractCollection.__init__(self, sourceCollection)
def clear(self):
self._front = None
self._rear = None
self._size = 0
def __str__(self):
return "{" + " ,".join(map(str, self._items)) + "}"
def __iter__(self):
return iter(self._items)
def add(self, item):
self._items.append(item)
self._size += 1
self._rear = self._items[self._size - 1]
self._front = self._items[0]
def pop(self):
if self.isEmpty():
raise KeyError("Queue is Empty")
else:
oldItem = self._items[0]
self._size -= 1
if self.isEmpty():
self._front = None
self._rear = None
self._items = list()
else:
self._front = self._items[1]
self._rear = self._items[self._size - 1]
self._items = self._items[1:(self._size - 1)]
return oldItem
def test(QueueType):
queue = ArrayQueue()
for item in range(1,7):
queue.add(item)
print(queue)
if __name__ == "__main__":
test(ArrayQueue)
循环数组实现队列
#! /usr/bin/env python
# -*- coding: utf-8 -*-
'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/3 6:28
file: arraystack.py
'''
class Array(object):
def __init__(self, capacity, fillValue = None):
self._items = list()
for item in range(capacity):
self._items.append(fillValue)
def __iter__(self):
return iter(self._items)
def __len__(self):
return len(self._items)
def __str__(self):
return str(self._items)
def __getitem__(self, index):
return self._items[index]
def __setitem__(self, index, newItem):
self._items[index] = newItem
class Node(object):
def __init__(self, data, next):
self.data = data
self.next = next
def __iter__(self):
cursor = self
while cursor != None:
yield cursor.data
cursor = cursor.next
class AbstractCollection(object):
def __init__(self, sourceCollection):
self._size = 0
if sourceCollection:
for item in sourceCollection:
self.add(item)
def isEmpty(self):
return len(self) == 0
def __add__(self, other):
result = type(self)(self)
for item in other:
result.add(item) # add方法在type(self)中一定要实现
return result
def __len__(self):
return self._size
def __str__(self):
return str(self)
def __eq__(self, other):
if self is other: return True
if type(self) != type(other) or\
len(self) != len(other):
return False
otherItem = iter(other) # iter为内置函数
for item in self:
if item != next(otherItem):
return False
return True
class LinkedQueue(AbstractCollection):
def __init__(self, souceCollenction=None):
self._front = None
self._rear = None
AbstractCollection.__init__(self, souceCollenction)
def __iter__(self):
def visitNode(node):
if not node is None:
visitNode(node.next)
temp.append(node.data)
temp = list()
visitNode(self._front)
return iter(temp)
def __str__(self):
return "{" + ' ,'.join(map(str, iter(self))) + "}"
def clear(self):
self._size = 0
self._items = None
def add(self, item):
newNode = Node(item, None)
if self.isEmpty():
self._front = newNode
else:
self._rear.next = newNode
self._rear = newNode
self._size += 1
def pop(self):
oldItem = self._front.data
self._front = self._front.next
self._size -= 1
if self._front == None:
self._rear = None
return oldItem
class LoopArrayQueue(AbstractCollection):
DEFAULTSIZE = 8
def __init__(self, sourceCollection=None):
self._front = None
self._rear = None
self._items = Array(LoopArrayQueue.DEFAULTSIZE)
AbstractCollection.__init__(self, sourceCollection)
def clear(self):
self._front = None
self._rear = None
self._items = None
self._size = 0
def __str__(self):
return "{" + " ,".join(map(str, self._items)) + "}"
def __iter__(self):
return iter(self._items)
def add(self, item):
if self.isEmpty():
"""队列为空,直接入队"""
self._items[0] = item
self._size += 1
self._front = 0
self._rear = 0
elif self._size >= LoopArrayQueue.DEFAULTSIZE:
"""队列占满,需要扩容时"""
temp = Array(self._size + 1)
if self._front < self._rear:
for i in range(0, self._rear + 1):
temp[i] = self._items[i]
elif self._front > self._rear:
for i in range(self._front, self._size):
temp[i - self._front] = self._items[i]
for j in range(0, self._rear + 1):
temp[self._size - self._front + 1 + j] = self._items[self._size - self._front + 1 + j]
temp[self._size] = item
self._items = temp
self._size += 1
self.front = 0
self._rear = self._size - 1
else:
self._items.__setitem__(self._size, item)
self._size += 1
self._rear = self._size - 1
self._front = 0
def pop(self):
if self.isEmpty():
raise KeyError("Queue is Empty")
else:
oldItem = self._items[0]
self._size -= 1
if self.isEmpty():
self._front = None
self._rear = None
self._items = list()
else:
self._items = self._items[1:self._size]
self._front = 0
self._rear = self._size - 1
return oldItem
def test(QueueType):
queue = QueueType()
for item in range(1,12):
queue.add(item)
print(queue)
if __name__ == "__main__":
"""{1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11}"""
test(LoopArrayQueue)
"""{11 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1}"""
test(LinkedQueue)