优先队列

#! /usr/bin/env python
# -*- coding: utf-8 -*-

'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/11 21:53
'''

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 Array(object):
	def __init__(self, capacity, fillValue=None):
		self._items = list()
		for item in range(capacity):
			self._items.append(fillValue)

	def __str__(self):
		return str(self._items)

	def __len__(self):
		return len(self._items)

	def __iter__(self):
		return iter(self._items)

	def __getitem__(self, index):
		return self._items[index]

	def __setitem__(self, index, newItem):
		self._items[index] = newItem


# 包装器类,将不能比较的对象构建为可比较对象的包装器类
class Comparable(object):
	"""Wrapper class for items that are not comparable"""

	def __init__(self, data, priority=1):
		self._data = data
		self._priority = priority

	def __str__(self):
		"""Returns  the string rep of the contained datum."""
		return str(self._data)

	def __eq__(self, other):
		"""Returns True if the contained priorities are equal
		or False otherwise"""
		if self is other:return True
		if type(self) != type(other): return False
		return self._priority == other._priority

	def __lt__(self, other):
		"""Returns True if self's priority < other's priority,
		or False otherwise"""
		return self._priority < other._priority

	def __le__(self, other):
		return self._priority <= other._priority

	def getData(self):
		return self._data

	def getPriority(self):
		"""Returns the contained priority
		"""
		return self._priority


class AbstractCollection(object):

	def __init__(self, sourceColletion):
		self._size = 0
		if sourceColletion:
			for item in sourceColletion:
				self.add(item)

	def isEmpty(self):
		return len(self) == 0

	def __iter__(self):
		return iter(self)

	def __len__(self):
		return self._size

	def __add__(self, other):
		result = type(self)(self)
		for item in other:
			result.add(item)
		return result

	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)
		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._front= 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 LinkedPriorityQueue(LinkedQueue):

	def __init__(self, sourceCollection=None):
		LinkedQueue.__init__(self, sourceCollection)

	def add(self, newItem):
		if self.isEmpty() or newItem >= self._rear.data:
			LinkedQueue.add(self, newItem)
		else:
			probe = self._front
			while newItem >= probe.data:
				trailer = probe
				probe = probe.next
			newNode = Node(newItem, probe)
			if probe == self._front:
				self._front = newNode
			else:
				trailer.next = newNode
			self._size += 1

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[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 insertSort(lyst):
	i = 1
	while i < len(lyst):
		item = lyst[i]
		j = i - 1
		while j >= 0:
			if item < lyst[j]:
				lyst[j + 1] = lyst[j]
				j -= 1
			else:
				break
		lyst[j + 1] = item
		i += 1
	return lyst

class ArrayPriorityQueue(AbstractCollection):
	"""
	基于数组的优先队列可以用动态数组实现吗?
	"""
	DEFAULTSIZE = 8
	def __init__(self, sourceCollection=None):
		# self._front = None
		self._rear = None
		self._items = Array(ArrayPriorityQueue.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 >= ArrayPriorityQueue.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]
			for i in range(self._size):
				temp[i] = self._items[i]
			temp[self._size] = item
			self._size += 1
			self._items = insertSort(temp)
			# self.front = 0
			self._rear = self._size - 1
		else:
			self._items[self._size] = item
			# Array并没有实现Array[0:self._size]这样的类似list的方法,所以不能用
			# self._items = insertSort(self._items[0:self._size])
			# 对数组Array用插入排序算法
			if self._size == 1:
				if self._items[0] > item: self._items[0], self._items[1] = self._items[1], self._items[0]
			else:
				j = self._size - 1
				while j >= 0:
					if self._items[j] > item:
						self._items[j + 1] = self._items[j]
						j -= 1
					else:
						break
				self._items[j + 1] = 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(12,1,-1):
		queue.add(item)
	print(queue)

if __name__ == "__main__":
	"""{2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12}"""
	test(LinkedQueue)
	"""{12 ,11 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,3 ,2}"""
	test(LinkedPriorityQueue)
	"""{2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12}"""
	test(ArrayPriorityQueue)
	"""{12 ,11 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,3 ,2}"""
	test(LoopArrayQueue)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值