表达式树

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

'''
@author: liudaoqiang
@file: studycase
@time: 2018/9/25 21:54
'''

import unittest


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 index in range(capacity):
			self._items.append(fillValue)

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

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

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

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

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


class TwoWayNode(Node):
	def __init__(self, data, prev=None, next=None):
		Node.__init__(self, data, next)
		self._prev = prev


class AbstractCollection(object):

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

	def isEmpty(self):
		return self._size == 0

	def __add__(self, other):
		result = type(self)(self)
		for item in other:
			result.add(item)
		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
		else:
			otherIter = iter(other)
			for item in self:
				if item != next(otherIter):
					return False
			return True


class AbstractStack(AbstractCollection):
	"""AbstractStack of ArrayStack and LinkedStack"""

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

	def add(self, item):
		self.push(item)  # 在ArrayStack和LinkedStack实现push方法


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 LinkedStack(AbstractStack):

	def __init__(self, sourceCollection=None):
		self._items = None
		AbstractStack.__init__(self, sourceCollection)

	# Accessors
	def __iter__(self):
		def visitNode(node):
			if node != None:
				visitNode(node.next)
				templist.append(node.data)
		templist = list()
		visitNode(self._items)
		return iter(templist)

	def peek(self):
		if self.isEmpty():
			raise KeyError("The Stack is empty")
		return self._items.data

	def __str__(self):
		return "{" + " ,".join(map(str, iter(self))) + "}"

	# Mutator
	def clear(self):
		self._size = 0
		self._items = None

	def push(self, item):
		self._items = Node(item, self._items)
		self._size += 1

	def pop(self):
		if self.isEmpty():
			raise KeyError("The stack is empty")
		oldItem = self._items.data
		self._items = self._items.next
		self._size -= 1
		return oldItem


class BSTNode(object):
	"""Represents a node for a linked binary search tree."""

	def __init__(self, data, left=None, right=None):
		self.data = data
		self.left = left
		self.right = right


class LinkedBST(AbstractCollection):
	"""A Linked-based binary search tree implementation"""

	def __init__(self, sourceCollection=None):
		self._root = None
		AbstractCollection.__init__(self, sourceCollection)

	def find(self, item):
		# Helper function to search the binary tree
		def recurse(node):
			if node is None:
				return None
			elif item == node.data:
				return node.data
			elif item < node.data:
				return recurse(node.left)
			else:
				return recurse(node.right)

		# Top-level call on the root node
		return recurse(self._root)

	def inorder(self):
		"""中序遍历"""
		lyst = list()
		def recurse(node):
			if node != None:
				recurse(node.left)
				lyst.append(node.data)
				recurse(node.right)
		recurse(self._root)
		return iter(lyst)  # 返回一个迭代器

	def preorder(self):
		lyst = list()
		def recurse(node):
			if node != None:
				lyst.append(node.data)
				recurse(node.left)
				recurse(node.right)
		recurse(self._root)
		return iter(lyst)

	def postorder(self):
		lyst = list()
		def recurse(node):
			if node != None:
				recurse(node.left)
				recurse(node.right)
				lyst.append(node.data)
		recurse(self._root)
		return iter(lyst)  # 返回一个迭代器

	def levelorder(self):
		queue = LinkedQueue()
		queue.add(self._root)
		lyst = list()
		while not queue.isEmpty():
			node = queue.pop()
			lyst.append(node.data)
			if node.left:
				queue.add(node.left)
			if node.right:
				queue.add(node.right)
		return iter(lyst)  # 返回一个迭代器

	def __iter__(self):
		"""Supports a preorder traversal on a view of self."""
		linkedstack = LinkedStack()
		lyst = list()
		linkedstack.push(self._root)
		while not linkedstack.isEmpty():
			temp = linkedstack.pop()
			yield temp.data
			if temp.right is not None:
				linkedstack.push(temp.right)
			if temp.left is not None:
				linkedstack.push(temp.left)

	def __str__(self):
		def recurse(node, level):
			s = ""
			if node != None:
				s += recurse(node.right, level + 1)
				s += "| " * level
				s += str(node.data) + "\n"
				s += recurse(node.left, level + 1)
			return s

		return recurse(self._root, 0)

	def add(self, item):

		def recurse(node):
			if item < node.data:
				if node.left == None:
					node.left = BSTNode(item)
				else:
					recurse(node.left)
			elif node.right == None:
				node.right = BSTNode(item)
			else:
				recurse(node.right)
		if self.isEmpty():
			self._root = BSTNode(item)
		else:
			recurse(self._root)
		self._size += 1

	def __contains__(self, item):
		return self.find(item) != None

	def clear(self):
		self._root = None
		self._size = 0

	def remove(self, item):
		"""Precondition: item is in self.
		Raises: KeyError if item is not in self.
		postcondition: item is removed from self."""
		if not item in self:
			raise KeyError("Item not in tree.""")

		# Helper function to adjust placement of an item
		def liftMaxInLeftSubtreeToTop(top):
			# Replace top's datum with the maximum datum in the left subtree
			# Pre:  top has a left child
			# Post: the maximum node in top's left subtree
			#       has been removed
			# Post: top.data = maximum value in top's left subtree
			parent = top
			currentNode = top.left
			while not currentNode.right == None:
				parent = currentNode
				currentNode = currentNode.right
			top.data = currentNode.data
			if parent == top:
				top.left = currentNode.left
			else:
				parent.right = currentNode.left

		# Begin main part of the method
		if self.isEmpty(): return None

		# Attempt to locate the node containing the item
		itemRemoved = None
		preRoot = BSTNode(None)
		preRoot.left = self._root
		parent = preRoot
		direction = 'L'
		currentNode = self._root
		while not currentNode == None:
			if currentNode.data == item:
				itemRemoved = currentNode.data
				break
			parent = currentNode
			if currentNode.data > item:
				direction = 'L'
				currentNode = currentNode.left
			else:
				direction = 'R'
				currentNode = currentNode.right

		# Return None if the item is absent
		if itemRemoved == None: return None
		# The item is present, so remove its node
		# Case 1: The node has a left and a right child
		#         Replace the node's value with the maximum value in the
		#         left subtree
		#         Delete the maximium node in the left subtree
		if not currentNode.left == None \
				and not currentNode.right == None:
			liftMaxInLeftSubtreeToTop(currentNode)
		else:

			# Case 2: The node has no left child
			if currentNode.left == None:
				newChild = currentNode.right

			# Case 3: The node has no right child
			else:
				newChild = currentNode.left

			# Case 2 & 3: Tie the parent to the new child
			if direction == 'L':
				parent.left = newChild
			else:
				parent.right = newChild

		# All cases: Reset the root (if it hasn't changed no harm done)
		#            Decrement the collection's size counter
		#            Return the item
		self._size -= 1
		if self.isEmpty():
			self._root = None
		else:
			self._root = preRoot.left
		return itemRemoved

	def replace(self, item, newItem):
		"""
		If item is in self, replaces it with newItem and
		returns the old item, or returns None otherwise.
		"""
		probe = self._root
		while probe != None:
			if probe.data == item:
				oldData = probe.data
				probe.data = newItem
				return oldData
			elif probe.data > item:
				probe = probe.left
			else:
				probe = probe.right
		return None

# class TestCase(unittest.TestCase):
# 	pass

def main():
	tree = LinkedBST()
	print("Adding D B A C F E G")
	tree.add("D")
	tree.add("B")
	tree.add("A")
	tree.add("C")
	tree.add("F")
	tree.add("E")
	tree.add("G")

	print("\nExpect True for A in tree: ", "A" in tree)

	print("\nString:\n" + str(tree))

	clone = LinkedBST(tree)
	print("\nClone:\n" + str(clone))

	print("Expect True for tree == clone: ", tree == clone)

	print("\nFor loop: ", end="")
	for item in tree:
		print(item, end=" ")

	print("\n\ninorder traversal: ", end="")
	for item in tree.inorder(): print(item, end=" ")

	print("\n\npreorder traversal: ", end="")
	for item in tree.preorder(): print(item, end=" ")

	print("\n\npostorder traversal: ", end="")
	for item in tree.postorder(): print(item, end=" ")

	print("\n\nlevelorder traversal: ", end="")
	for item in tree.levelorder(): print(item, end=" ")

	print("\n\nRemoving all items:", end=" ")
	for item in "ABCDEFG":
		print(tree.remove(item), end=" ")

	print("\n\nExpect 0: ", len(tree))

	tree = LinkedBST(range(1, 16))
	print("\nAdded 1..15:\n" + str(tree))

	lyst = list(range(1, 16))
	import random
	random.shuffle(lyst)
	tree = LinkedBST(lyst)
	print("\nAdded ", lyst, "\n" + str(tree))


if __name__ == "__main__":
	main()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值