表达式树
程序员文章站
2022-03-03 10:29:47
...
#! /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()
上一篇: 关于浙江大学软件学院的面试经验