实现链表和数组队列

链表实现的队列,除了__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)

猜你喜欢

转载自blog.csdn.net/liudaoqiang_tj/article/details/82490686