class Node(object): '''A single node in the tree; contains a value, pointers to the left and right subtrees, as well as how many nodes there are in the subtree rooted at this node.''' def __init__(self, value): '''Create a new node containing value with no children.''' self.value = value self.left = None self.right = None self.size = 1 # You should not add any more attributes to this class.class TreeList(object): '''A partial implementation of a list using a binary tree.''' def __init__(self): '''Create an empty list.''' self.root = None # You should not add any more attributes to this class. def set_root(self, new_root): '''Set the root of the tree to be new_root.''' self.root = new_root def get_root(self): '''Return a pointer to the root node of this tree.''' return self.root def add_left_or_right(self, r_node, value, isleft): if isleft: r_node.left = Node(value) else: r_node.right = Node(value) def find_node(self, r_node, add, value, index, insert): i = add + r_node.size - 1 if r_node.right is not None: i -= r_node.right.size if i + 1 == index: if r_node.right is None: if insert: self.add_left_or_right(r_node, value, False) else: return r_node else: add += 1 r_node.size += 1 return self.find_node(r_node.right, add, value, index, insert) elif i == index: if r_node.left is None: if insert: self.add_left_or_right(r_node, value, True) else: return r_node else: r_node.size += 1 return self.find_node(r_node.left, add, value, index, insert) else: if i > index: r_node.size += 1 return self.find_node(r_node.left, add, value, index, insert) else: add += 1 r_node.size += 1 return self.find_node(r_node.right, add, value, index, insert) def get(self, index): '''Return element index of the list.''' if index < 0: raise Exception("Index is less than zero.") elif self.root is not None: if index > self.root.size - 1: raise Exception("Index exceeds number of elements in list.") elif self.root is None and index > 0: raise Exception("Index exceeds number of elements in list.") current = self.root _left = current.left _right = current.right if _left is not None: if index == _left.size: needed = current elif index < _left.size: #Working with left side. needed = self.find_node(_left, 0, 0, index, False) else: #Working with right side. addition = current.size - current.right.size needed = self.find_node(_right, addition, 0, index, False) elif _right is not None: #Working with right side. if index == 0: needed = current else: needed = self.find_node(_right, 1, 0, index, False) return needed.value def insert(self, index, value): '''Insert value at position index, shifting everything else to the right. Always inserts value to be a leaf.''' if index < 0: raise Exception("Index is less than zero.") elif self.root is not None: if index > self.root.size: raise Exception("Index exceeds number of elements in list.") elif self.root is None and index > 0: raise Exception("Index exceeds number of elements in list.") if self.root is None: self.root = Node(value) return current = self.root _left = current.left _right = current.right if index == 0: while current is not None: current.size += 1 before = current current = current.left before.left = Node(value) return if index == current.size: while current is not None: current.size += 1 before = current current = current.right before.right = Node(value) return if _left is not None: if index <= _left.size: #Working with left side. self.find_node(_left, 0, value, index, True) else: #Working with right side. addition = current.size - current.right.size current.size += 1 self.find_node(_right, addition, value, index, True) elif _right is not None: #Working with right side. self.find_node(_right, 1, value, index, True) current.size += 1 def size(self): '''How many elements are in the list.''' if self.root is None: return 0 return self.root.sizeif __name__ == "__main__": my_list = TreeList() my_list.insert(0, 1) my_list.insert(1, 2) # The "list" is now [1,2] print my_list.get(1) # Should print 2 my_list.insert(1, 3) # The "list" is now [1,3,2] print my_list.get(1) # Should print 3 try: my_list.insert(4, 7) # Should raise an exception, my_list should be unchanged. except Exception, e: print 'Exception handled.' print my_list.get(1) # Should print 3