01-03 BinarySearchTree
01.An implementation of the BinarySearchTree ADT is shown in the answer box for this question. Extend the BinarySearchTree class by adding the method __contains__(self, value)
which takes a value as a parameter. This method should search for the parameter value in the binary search tree. If the value is found, the method should return True, and False otherwise.
class BinarySearchTree:
def __init__(self, data, left=None, right=None):
self.__data = data
self.__left = left
self.__right = right
def insert_left(self, new_data):
if self.__left == None:
self.__left = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, left=self.__left)
self.__left = t
def insert_right(self, new_data):
if self.__right == None:
self.__right = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, right=self.__right)
self.__right = t
def get_left(self):
return self.__left
def get_right(self):
return self.__right
def set_left(self, left):
self.__left = left
def set_right(self, right):
self.__right = right
def set_data(self, data):
self.__data = data
def get_data(self):
return self.__data
def __contains__(self,value):
if self.get_data()==value:
return True
elif self.get_data()>value and self.get_left()!=None:
return self.get_left().__contains__(value)
elif self.get_data()<value and self.get_right()!=None:
return self.get_right().__contains__(value)
else:
return False
02.An implementation of the BinarySearchTree ADT is shown in the answer box for this question. Extend the BinarySearchTree class by adding the method search(self, value)
which takes a value as a parameter. This method should search for the parameter value in the binary search tree. If the value is found, the method should return the found object, and None otherwise.
class BinarySearchTree:
def __init__(self, data, left=None, right=None):
self.__data = data
self.__left = left
self.__right = right
def insert_left(self, new_data):
if self.__left == None:
self.__left = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, left=self.__left)
self.__left = t
def insert_right(self, new_data):
if self.__right == None:
self.__right = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, right=self.__right)
self.__right = t
def get_left(self):
return self.__left
def get_right(self):
return self.__right
def set_left(self, left):
self.__left = left
def set_right(self, right):
self.__right = right
def set_data(self, data):
self.__data = data
def get_data(self):
return self.__data
def __contains__(self,value):
if self.get_data()==value:
return True
elif self.get_data()>value and self.get_left()!=None:
return self.get_left().__contains__(value)
elif self.get_data()<value and self.get_right()!=None:
return self.get_right().__contains__(value)
else:
return False
def search(self, value):
if self.get_data()==value:
return self
elif self.get_data()>value and self.get_left()!=None:
return self.get_left().search(value)
elif self.get_data()<value and self.get_right()!=None:
return self.get_right().search(value)
else:
return None
03.An implementation of the BinarySearchTree ADT is shown in the answer box for this question. Extend the BinarySearchTree class by adding the method insert(self, value)
which takes a value as a parameter. This method should insert a data value into the binary search tree. Inserting a value in the correct position is similar to searching because we try to maintain the rule that the left subtree is less than the root and the right subtree is greater than the root.
class BinarySearchTree:
def __init__(self, data, left=None, right=None):
self.__data = data
self.__left = left
self.__right = right
def insert_left(self, new_data):
if self.__left == None:
self.__left = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, left=self.__left)
self.__left = t
def insert_right(self, new_data):
if self.__right == None:
self.__right = BinarySearchTree(new_data)
else:
t = BinarySearchTree(new_data, right=self.__right)
self.__right = t
def get_left(self):
return self.__left
def get_right(self):
return self.__right
def set_left(self, left):
self.__left = left
def set_right(self, right):
self.__right = right
def set_data(self, data):
self.__data = data
def get_data(self):
return self.__data
def insert(self, new_data):
if new_data == self.__data:
return
elif new_data < self.__data:
if self.__left == None:
self.__left = BinarySearchTree(new_data)
else:
self.__left.insert(new_data)
else:
if self.__right == None:
self.__right = BinarySearchTree(new_data)
else:
self.__right.insert(new_data)
04-05 create_bst_from_sorted(values)
04.Define a function called create_bst_from_list(values)
which takes a list of values as a parameter. The function should create a binary search tree by using the insert() method.
def create_bst_from_list(values):
tree=BinarySearchTree(values[0])
for num in values[1:]:
tree.insert(num)
return tree
05.Define a function called create_bst_from_sorted(values)
which takes a list of sorted values as a parameter. The function should create a balanced binary search tree.
A tree is balanced if, for every node, its left and right sub-trees vary in height by at most, one.
def create_bst_from_sorted(values):
if len(values)==0:
return None
mid=len(values)//2
if len(values)>0:
tree=BinarySearchTree(values[mid])
if len(values[:mid])>0:
tree.set_left(create_bst_from_sorted(values[:mid]))
if len(values[mid+1:])>0:
tree.set_right(create_bst_from_sorted(values[mid+1:]))
return tree
06.Define a function called get_bst_postorder(bst)
which takes a binary search tree as a parameter. The function should return a Python list containing values in the post-order traversal of the parameter binary search tree.
def get_bst_postorder(bst):
if bst==None:
return []
else:
left=bst.get_left()
right=bst.get_right()
return get_bst_postorder(left)+get_bst_postorder(right)+[bst.get_data()]
07.Define a function named get_maximum(bst)
which takes a binary search tree as a parameter and returns the largest value in the parameter binary search tree. You should NOT search all values in the binary search tree.
def get_maximum(bst):
if bst.get_right()==None:
return bst.get_data()
num=bst.get_data()
return max(num,get_maximum(bst.get_right()))
08.Define a function called print_insert_position(bst, value)
which takes a binary search tree and a value to be inserted to the tree as parameters. The function should NOT modify the tree at all - instead, it should simply print the position at which value would be inserted into the tree. This involves printing the node under which the value would be inserted, after either "To the left of" or "To the right of". If the data value to be inserted already exists in the tree, then the function should print "Duplicate".
def print_insert_position(bst,value):
if bst.get_data()==value:
print("Duplicate")
return
elif bst.get_data()>value:
if bst.get_left()==None:
print(f"To the left of {bst.get_data()}")
return
else:
print_insert_position(bst.get_left(),value)
else:
if bst.get_right()==None:
print(f"To the right of {bst.get_data()}")
return
else:
print_insert_position(bst.get_right(),value)
09.Define a function named is_binary_search_tree(my_tree, min_value, max_value)
which takes a binary tree as a parameter and returns True if the given binary tree is a binary search tree, and False otherwise.
def is_binary_search_tree(my_tree, min_value, max_value):
if my_tree==None:
return True
elif my_tree.get_data()<=min_value or my_tree.get_data()>=max_value:
return False
elif not is_binary_search_tree(my_tree.get_right(),my_tree.get_data(),max_value):
return False
elif not is_binary_search_tree(my_tree.get_left(),min_value,my_tree.get_data()):
return False
return True
01-07 PriorityQueue
class PriorityQueue:
def __init__(self):
self.__binary_heap = [0]
self.__size = 0
def __str__(self):
return "{}".format(self.__binary_heap)
def __len__(self):
return self.__size
def add_all(self, a_list):
for i in a_list:
self.__binary_heap.append(i)
self.__size += 1
def percolate_up(self, ind):
while ind > 1:
if self.__binary_heap[ind] < self.__binary_heap[ind // 2]:
self.__binary_heap[ind], self.__binary_heap[ind // 2]\
= self.__binary_heap[ind // 2], self.__binary_heap[ind]
ind = ind // 2
def insert(self, data):
self.__binary_heap.append(data)
self.__size += 1
i = self.__size
while i > 1:
if self.__binary_heap[i] < self.__binary_heap[i//2]:
self.__binary_heap[i], self.__binary_heap[i//2] \
= self.__binary_heap[i//2], self.__binary_heap[i]
i = i // 2
def delete_minimum(self):
a = self.__binary_heap[1]
self.__binary_heap[1] = self.__binary_heap[self.__size]
self.__binary_heap.pop()
self.__size -= 1
self.percolate_down(1)
return a
def get_smaller_child_index(self, ind):
if ind * 2 + 1 > self.__size: # 如果只有左节点
return ind * 2
else:
if self.__binary_heap[ind * 2] < self.__binary_heap[ind * 2 + 1]:
return ind * 2
else:
return ind * 2 + 1
def percolate_down(self, ind):
while (ind * 2) <= self.__size:
smallest_child = self.get_smaller_child_index(ind) # 比较出较小的子节点
if self.__binary_heap[ind] > self.__binary_heap[smallest_child]:
self.__binary_heap[ind], self.__binary_heap[smallest_child]\
= self.__binary_heap[smallest_child], self.__binary_heap[ind]
ind = smallest_child
def create_heap_fast(self, a_list):
i = len(a_list) // 2
self.__size = len(a_list)
for j in a_list:
self.__binary_heap.append(j)
while i > 0:
self.percolate_down(i)
i -= 1
08.Define a function called heap_sort(values)
which takes a list of values as a parameter and returns a new list of elements which are in ascending order. The function should use the insert() and delete_minimum() methods listed in the PriorityQueue class.
def heap_sort(values):
new = []
a_queue = PriorityQueue()
for i in values:
a_queue.insert(i)
while len(a_queue) != 0:
new.append(a_queue.delete_minimum())
return new