From 637e6ff126928129a10ddcadaa9e3d31b2aae23c Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Thu, 10 Oct 2019 21:18:49 +0800 Subject: [PATCH 1/9] Update binary_search_tree.py remove some bugs --- .../binary_tree/binary_search_tree.py | 361 ++++++++---------- 1 file changed, 159 insertions(+), 202 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 1e6c17112e81..5e0a127da741 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -2,202 +2,177 @@ A binary search Tree """ - class Node: - def __init__(self, label, parent): - self.label = label + def __init__(self, data, parent): + self.data = data self.left = None self.right = None - # Added in order to delete a node easier - self.parent = parent + self.parent = parent # Added in order to delete a node easier - def getLabel(self): - return self.label + def getdata(self): + return self.data - def setLabel(self, label): - self.label = label - - def getLeft(self): + def getleft(self): return self.left - def setLeft(self, left): - self.left = left - - def getRight(self): + def getright(self): return self.right + def getparent(self): + return self.parent + + def setdata(self, data): + self.data = data + + def setleft(self, left): + self.left = left + def setRight(self, right): self.right = right - def getParent(self): - return self.parent - - def setParent(self, parent): + def setparent(self, parent): self.parent = parent - class BinarySearchTree: def __init__(self): self.root = None - # Insert a new node in Binary Search Tree with value label - def insert(self, label): - # Create a new Node - new_node = Node(label, None) - # If Tree is empty - if self.empty(): - self.root = new_node - else: - # If Tree is not empty - curr_node = self.root - # While we don't get to a leaf - while curr_node is not None: - # We keep reference of the parent node - parent_node = curr_node - # If node label is less than current node - if new_node.getLabel() < curr_node.getLabel(): - # We go left - curr_node = curr_node.getLeft() - else: - # Else we go right - curr_node = curr_node.getRight() - # We insert the new node in a leaf - if new_node.getLabel() < parent_node.getLabel(): - parent_node.setLeft(new_node) - else: - parent_node.setRight(new_node) - # Set parent to the new node - new_node.setParent(parent_node) - - def delete(self, label): - if not self.empty(): - # Look for the node with that label - node = self.getNode(label) - # If the node exists - if node is not None: - # If it has no children - if node.getLeft() is None and node.getRight() is None: - self.__reassignNodes(node, None) - node = None - # Has only right children - elif node.getLeft() is None and node.getRight() is not None: - self.__reassignNodes(node, node.getRight()) - # Has only left children - elif node.getLeft() is not None and node.getRight() is None: - self.__reassignNodes(node, node.getLeft()) - # Has two children - else: - # Gets the max value of the left branch - tmpNode = self.getMax(node.getLeft()) - # Deletes the tmpNode - self.delete(tmpNode.getLabel()) - # Assigns the value to the node to delete and keesp tree structure - node.setLabel(tmpNode.getLabel()) + def __str__(self): + """ + Return a string of all the Nodes. + In Order Traversal + """ + nodelist = self.__InOrderTraversal(self.root) + str = " ".join([repr(i.getdata()) for i in nodelist]) + return str - def getNode(self, label): - curr_node = None - # If the tree is not empty - if not self.empty(): - # Get tree root - curr_node = self.getRoot() - # While we don't find the node we look for - # I am using lazy evaluation here to avoid NoneType Attribute error - while curr_node is not None and curr_node.getLabel() is not label: - # If node label is less than current node - if label < curr_node.getLabel(): - # We go left - curr_node = curr_node.getLeft() - else: - # Else we go right - curr_node = curr_node.getRight() - return curr_node + def __InOrderTraversal(self, node): + nodeList = list() + if node is not None: + nodeList.insert(0, node) # Preorder Traversal + nodeList = nodeList + self.__InOrderTraversal(node.getleft()) + self.__InOrderTraversal(node.getright()) + return nodeList - def getMax(self, root=None): - if root is not None: - curr_node = root + def __isRightChildren(self, node): + if(node == node.getparent().getright()): + return True else: - # We go deep on the right branch - curr_node = self.getRoot() - if not self.empty(): - while curr_node.getRight() is not None: - curr_node = curr_node.getRight() - return curr_node + return False - def getMin(self, root=None): - if root is not None: - curr_node = root - else: - # We go deep on the left branch - curr_node = self.getRoot() - if not self.empty(): - curr_node = self.getRoot() - while curr_node.getLeft() is not None: - curr_node = curr_node.getLeft() - return curr_node + def __reassignNodes(self, node, newChildren): + if(newChildren is not None): # reset its kids + newChildren.setparent(node.getparent()) + if(node.getparent() is not None): # reset its parenst + if(self.__isRightChildren(node)): # If it is the Right Children + node.getparent().setRight(newChildren) + else: # Else it is the left children + node.getparent().setleft(newChildren) + else: # no parent => root + self.root = newChildren def empty(self): if self.root is None: return True - return False - - def __InOrderTraversal(self, curr_node): - nodeList = [] - if curr_node is not None: - nodeList.insert(0, curr_node) - nodeList = nodeList + self.__InOrderTraversal(curr_node.getLeft()) - nodeList = nodeList + self.__InOrderTraversal(curr_node.getRight()) - return nodeList + else: + return False + + def insert(self, data): + """ + Insert a new node in Binary Search Tree with value label + """ + new_node = Node(data, None) # Create a new Node + if self.empty(): # If Tree is empty + self.root = new_node # set its root + else: # If Tree is not empty + parent_node = self.root # from root + while True: # While we don't get to a leaf + if data < parent_node.getdata(): # We go left + if parent_node.getleft() == None: + parent_node.setleft(new_node) # We insert the new node in a leaf + break + else: + parent_node = parent_node.getleft() + else: # Else we go right + if parent_node.getright() == None: + parent_node.setRight(new_node) + break + else: + parent_node = parent_node.getright() + new_node.setparent(parent_node) # Set parent to the new node + + def getNode(self, data): + if self.empty(): + raise IndexError("Warning: 树是空的! 请使用非空的二叉树. ") + else: # If the tree is not empty + node = self.getRoot() + while node is not None and node.getdata() is not data: # using lazy evaluation here to avoid NoneType Attribute error + if data < node.getdata(): + node = node.getleft() # We go left + else: + node = node.getright() # Else we go right + return node def getRoot(self): return self.root - def __isRightChildren(self, node): - if node == node.getParent().getRight(): - return True - return False - - def __reassignNodes(self, node, newChildren): - if newChildren is not None: - newChildren.setParent(node.getParent()) - if node.getParent() is not None: - # If it is the Right Children - if self.__isRightChildren(node): - node.getParent().setRight(newChildren) - else: - # Else it is the left children - node.getParent().setLeft(newChildren) - - # This function traversal the tree. By default it returns an - # In order traversal list. You can pass a function to traversal - # The tree as needed by client code - def traversalTree(self, traversalFunction=None, root=None): - if traversalFunction is None: - # Returns a list of nodes in preOrder by default + def getMax(self, node = None): + """ + We go deep on the right branch + """ + if(node is None): + node = self.getRoot() + if(not self.empty()): + while(node.getright() is not None): + node = node.getright() + return node + + def getMin(self, node = None): + """ + We go deep on the left branch + """ + if(node is None): + node = self.getRoot() + if(not self.empty()): + node = self.getRoot() + while(node.getleft() is not None): + node = node.getleft() + return node + + def delete(self, data): + node = self.getNode(data) # Look for the node with that label + if(node is not None): + if(node.getleft() is None and node.getright() is None): # If it has no children + self.__reassignNodes(node, None) + node = None + elif(node.getleft() is None): # Has only right children + self.__reassignNodes(node, node.getright()) + elif(node.getright() is None): # Has only left children + self.__reassignNodes(node, node.getleft()) + else: # Has two children + tmpNode = self.getMax(node.getleft()) # Gets the max value of the left branch + self.delete(tmpNode.getdata()) + node.setdata(tmpNode.getdata()) # Assigns the value to the node to delete and keesp tree structure + + def traversalTree(self, traversalFunction = None, root = None): + """ + This function traversal the tree. + You can pass a function to traversal the tree as needed by client code + """ + if(traversalFunction is None): # default return self.__InOrderTraversal(self.root) else: - # Returns a list of nodes in the order that the users wants to return traversalFunction(self.root) - # Returns an string of all the nodes labels in the list - # In Order Traversal - def __str__(self): - list = self.__InOrderTraversal(self.root) - str = "" - for x in list: - str = str + " " + x.getLabel().__str__() - return str - - -def InPreOrder(curr_node): - nodeList = [] +def postOrder(curr_node): + """ + postOrder (left, right, self) + """ + nodeList = list() if curr_node is not None: - nodeList = nodeList + InPreOrder(curr_node.getLeft()) - nodeList.insert(0, curr_node.getLabel()) - nodeList = nodeList + InPreOrder(curr_node.getRight()) + nodeList = postOrder(curr_node.getleft()) + postOrder(curr_node.getright()) + [curr_node] return nodeList - -def testBinarySearchTree(): +def binary_search_tree(): r""" Example 8 @@ -208,55 +183,37 @@ def testBinarySearchTree(): / \ / 4 7 13 """ - - r""" - Example After Deletion - 7 - / \ - 1 4 - - """ t = BinarySearchTree() - t.insert(8) - t.insert(3) - t.insert(6) - t.insert(1) - t.insert(10) - t.insert(14) - t.insert(13) - t.insert(4) - t.insert(7) - - # Prints all the elements of the list in order traversal - print(t.__str__()) - - if t.getNode(6) is not None: - print("The label 6 exists") + testlist = [8, 3, 6, 1, 10, 14, 13, 4, 7] + for i in testlist: + t.insert(i) + + #Prints all the elements of the list in order traversal + print(t) + #Gets all the elements of the tree In pre order + #And it prints them + nodelist = t.traversalTree(postOrder, t.root) + print(" ".join([repr(i.getdata()) for i in nodelist])) + + if(t.getNode(6) is not None): + print("The data 6 exists") else: - print("The label 6 doesn't exist") + print("The data 6 doesn't exist") - if t.getNode(-1) is not None: - print("The label -1 exists") + if(t.getNode(-1) is not None): + print("The data -1 exists") else: - print("The label -1 doesn't exist") - - if not t.empty(): - print(("Max Value: ", t.getMax().getLabel())) - print(("Min Value: ", t.getMin().getLabel())) + print("The data -1 doesn't exist") - t.delete(13) - t.delete(10) - t.delete(8) - t.delete(3) - t.delete(6) - t.delete(14) + if(not t.empty()): + print(("Max Value: ", t.getMax().getdata())) + print(("Min Value: ", t.getMin().getdata())) - # Gets all the elements of the tree In pre order - # And it prints them - list = t.traversalTree(InPreOrder, t.root) - for x in list: - print(x) + for i in testlist: + t.delete(i) + print(t) + t.getNode(6) if __name__ == "__main__": - testBinarySearchTree() + binary_search_tree() From e35de26af78d75877490cc7ff40c0b157b507fc3 Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Fri, 18 Oct 2019 17:53:00 +0800 Subject: [PATCH 2/9] Update binary_search_tree.py --- .../binary_tree/binary_search_tree.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 5e0a127da741..58422d3bf558 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -9,7 +9,7 @@ def __init__(self, data, parent): self.right = None self.parent = parent # Added in order to delete a node easier - def getdata(self): + def get_data(self): return self.data def getleft(self): @@ -43,7 +43,7 @@ def __str__(self): In Order Traversal """ nodelist = self.__InOrderTraversal(self.root) - str = " ".join([repr(i.getdata()) for i in nodelist]) + str = " ".join([repr(i.get_data()) for i in nodelist]) return str def __InOrderTraversal(self, node): @@ -86,7 +86,7 @@ def insert(self, data): else: # If Tree is not empty parent_node = self.root # from root while True: # While we don't get to a leaf - if data < parent_node.getdata(): # We go left + if data < parent_node.get_data(): # We go left if parent_node.getleft() == None: parent_node.setleft(new_node) # We insert the new node in a leaf break @@ -102,11 +102,11 @@ def insert(self, data): def getNode(self, data): if self.empty(): - raise IndexError("Warning: 树是空的! 请使用非空的二叉树. ") + raise IndexError("Warning: Tree is empty! please use another. ") else: # If the tree is not empty node = self.getRoot() - while node is not None and node.getdata() is not data: # using lazy evaluation here to avoid NoneType Attribute error - if data < node.getdata(): + while node is not None and node.get_data() is not data: # using lazy evaluation here to avoid NoneType Attribute error + if data < node.get_data(): node = node.getleft() # We go left else: node = node.getright() # Else we go right @@ -150,8 +150,8 @@ def delete(self, data): self.__reassignNodes(node, node.getleft()) else: # Has two children tmpNode = self.getMax(node.getleft()) # Gets the max value of the left branch - self.delete(tmpNode.getdata()) - node.setdata(tmpNode.getdata()) # Assigns the value to the node to delete and keesp tree structure + self.delete(tmpNode.get_data()) + node.setdata(tmpNode.get_data()) # Assigns the value to the node to delete and keesp tree structure def traversalTree(self, traversalFunction = None, root = None): """ @@ -193,7 +193,7 @@ def binary_search_tree(): #Gets all the elements of the tree In pre order #And it prints them nodelist = t.traversalTree(postOrder, t.root) - print(" ".join([repr(i.getdata()) for i in nodelist])) + print(" ".join([repr(i.get_data()) for i in nodelist])) if(t.getNode(6) is not None): print("The data 6 exists") @@ -206,8 +206,8 @@ def binary_search_tree(): print("The data -1 doesn't exist") if(not t.empty()): - print(("Max Value: ", t.getMax().getdata())) - print(("Min Value: ", t.getMin().getdata())) + print(("Max Value: ", t.getMax().get_data())) + print(("Min Value: ", t.getMin().get_data())) for i in testlist: t.delete(i) From ab67d4686bd811c8ab37e53c110444c4518cc575 Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Fri, 18 Oct 2019 22:56:43 +0800 Subject: [PATCH 3/9] Update binary_search_tree.py --- .../binary_tree/binary_search_tree.py | 248 +++++++++--------- 1 file changed, 121 insertions(+), 127 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 58422d3bf558..7359d4ebdf30 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -1,179 +1,166 @@ -""" +''' A binary search Tree -""" - +''' class Node: - def __init__(self, data, parent): - self.data = data + def __init__(self, value, parent): + self.value = value self.left = None self.right = None self.parent = parent # Added in order to delete a node easier - def get_data(self): - return self.data - - def getleft(self): - return self.left - - def getright(self): - return self.right - - def getparent(self): - return self.parent - - def setdata(self, data): - self.data = data - - def setleft(self, left): - self.left = left + def __repr__(self): + from pprint import pformat - def setRight(self, right): - self.right = right - - def setparent(self, parent): - self.parent = parent + if self.left is None and self.right is None: + return "'%s" % (self.value) + return pformat( + { + "%s" + % (self.value): (self.left, self.right) + }, + indent=1, + ) class BinarySearchTree: - def __init__(self): - self.root = None + def __init__(self, root = None): + self.root = root def __str__(self): """ - Return a string of all the Nodes. - In Order Traversal + Return a string of all the Nodes. + In Order Traversal """ - nodelist = self.__InOrderTraversal(self.root) - str = " ".join([repr(i.get_data()) for i in nodelist]) - return str + return str(self.root) - def __InOrderTraversal(self, node): - nodeList = list() - if node is not None: - nodeList.insert(0, node) # Preorder Traversal - nodeList = nodeList + self.__InOrderTraversal(node.getleft()) + self.__InOrderTraversal(node.getright()) - return nodeList + def __reassign_nodes(self, node, newChildren): + if(newChildren is not None): # reset its kids + newChildren.parent = node.parent + if(node.parent is not None): # reset its parenst + if(self.is_right(node)): # If it is the Right Children + node.parent.right = newChildren + else: + node.parent.left = newChildren + else: + self.root = newChildren - def __isRightChildren(self, node): - if(node == node.getparent().getright()): + def is_right(self, node): + if(node == node.parent.right): return True else: return False - def __reassignNodes(self, node, newChildren): - if(newChildren is not None): # reset its kids - newChildren.setparent(node.getparent()) - if(node.getparent() is not None): # reset its parenst - if(self.__isRightChildren(node)): # If it is the Right Children - node.getparent().setRight(newChildren) - else: # Else it is the left children - node.getparent().setleft(newChildren) - else: # no parent => root - self.root = newChildren - def empty(self): if self.root is None: return True else: return False - def insert(self, data): + def __insert(self, value): """ - Insert a new node in Binary Search Tree with value label + Insert a new node in Binary Search Tree with value label """ - new_node = Node(data, None) # Create a new Node + new_node = Node(value, None) # Create a new Node if self.empty(): # If Tree is empty - self.root = new_node # set its root + self.root = new_node # 则作为根节点 set its root else: # If Tree is not empty parent_node = self.root # from root while True: # While we don't get to a leaf - if data < parent_node.get_data(): # We go left - if parent_node.getleft() == None: - parent_node.setleft(new_node) # We insert the new node in a leaf + if value < parent_node.value: # We go left + if parent_node.left == None: + parent_node.left = new_node # We insert the new node in a leaf break else: - parent_node = parent_node.getleft() - else: # Else we go right - if parent_node.getright() == None: - parent_node.setRight(new_node) + parent_node = parent_node.left + else: + if parent_node.right == None: + parent_node.right = new_node break else: - parent_node = parent_node.getright() - new_node.setparent(parent_node) # Set parent to the new node + parent_node = parent_node.right + new_node.parent = parent_node - def getNode(self, data): + def insert(self, *values): + for value in values: + self.__insert(value) + return self + + def search(self, value): if self.empty(): - raise IndexError("Warning: Tree is empty! please use another. ") - else: # If the tree is not empty - node = self.getRoot() - while node is not None and node.get_data() is not data: # using lazy evaluation here to avoid NoneType Attribute error - if data < node.get_data(): - node = node.getleft() # We go left + raise IndexError("Warning: Tree is empty! please use another. ") # Warning: Tree is empty! please use another. + else: + node = self.root + while node is not None and node.value is not value: # Using lazy evaluation here to avoid NoneType Attribute error + if value < node.value: + node = node.left else: - node = node.getright() # Else we go right + node = node.right return node - def getRoot(self): - return self.root - - def getMax(self, node = None): + def get_max(self, node = None): """ - We go deep on the right branch + We go deep on the right branch """ if(node is None): - node = self.getRoot() + node = self.root if(not self.empty()): - while(node.getright() is not None): - node = node.getright() + while(node.right is not None): + node = node.right return node - def getMin(self, node = None): + def get_min(self, node = None): """ - We go deep on the left branch + We go deep on the left branch """ if(node is None): - node = self.getRoot() + node = self.root if(not self.empty()): - node = self.getRoot() - while(node.getleft() is not None): - node = node.getleft() + node = self.root + while(node.left is not None): + node = node.left return node - def delete(self, data): - node = self.getNode(data) # Look for the node with that label + def remove(self, value): + node = self.search(value) # Look for the node with that label if(node is not None): - if(node.getleft() is None and node.getright() is None): # If it has no children - self.__reassignNodes(node, None) + if(node.left is None and node.right is None): # If it has no children + self.__reassign_nodes(node, None) node = None - elif(node.getleft() is None): # Has only right children - self.__reassignNodes(node, node.getright()) - elif(node.getright() is None): # Has only left children - self.__reassignNodes(node, node.getleft()) - else: # Has two children - tmpNode = self.getMax(node.getleft()) # Gets the max value of the left branch - self.delete(tmpNode.get_data()) - node.setdata(tmpNode.get_data()) # Assigns the value to the node to delete and keesp tree structure - - def traversalTree(self, traversalFunction = None, root = None): + elif(node.left is None): # Has only right children + self.__reassign_nodes(node, node.right) + elif(node.right is None): # Has only left children + self.__reassign_nodes(node, node.left) + else: + tmpNode = self.get_max(node.left) # Gets the max value of the left branch + self.remove(tmpNode.value) + node.value = tmpNode.value # Assigns the value to the node to delete and keesp tree structure + + def preorder_traverse(self, node): + if node is not None: + yield node # Preorder Traversal + yield from self.preorder_traverse(node.left) + yield from self.preorder_traverse(node.right) + + def traversal_tree(self, traversalFunction = None): """ - This function traversal the tree. - You can pass a function to traversal the tree as needed by client code + This function traversal the tree. + You can pass a function to traversal the tree as needed by client code """ - if(traversalFunction is None): # default - return self.__InOrderTraversal(self.root) + if(traversalFunction is None): + return self.preorder_traverse(self.root) else: return traversalFunction(self.root) -def postOrder(curr_node): +def postorder(curr_node): """ - postOrder (left, right, self) + postOrder (left, right, self) """ nodeList = list() if curr_node is not None: - nodeList = postOrder(curr_node.getleft()) + postOrder(curr_node.getright()) + [curr_node] + nodeList = postorder(curr_node.left) + postorder(curr_node.right) + [curr_node] return nodeList def binary_search_tree(): - r""" + r''' Example 8 / \ @@ -182,38 +169,45 @@ def binary_search_tree(): 1 6 14 / \ / 4 7 13 - """ + + >>> t = BinarySearchTree().insert(8, 3, 6, 1, 10, 14, 13, 4, 7) + >>> print(" ".join([repr(i.value) for i in t.traversal_tree()])) + 8 3 1 6 4 7 10 14 13 + >>> print(" ".join([repr(i.value) for i in t.traversal_tree(postorder)])) + 1 4 7 6 3 13 14 10 8 + >>> BinarySearchTree().search(6) + Traceback (most recent call last): + ... + IndexError: Warning: Tree is empty! please use another. + ''' t = BinarySearchTree() testlist = [8, 3, 6, 1, 10, 14, 13, 4, 7] for i in testlist: t.insert(i) - #Prints all the elements of the list in order traversal + # Prints all the elements of the list in order traversal print(t) - #Gets all the elements of the tree In pre order - #And it prints them - nodelist = t.traversalTree(postOrder, t.root) - print(" ".join([repr(i.get_data()) for i in nodelist])) - if(t.getNode(6) is not None): - print("The data 6 exists") + if(t.search(6) is not None): + print("The value 6 exists") else: - print("The data 6 doesn't exist") + print("The value 6 doesn't exist") - if(t.getNode(-1) is not None): - print("The data -1 exists") + if(t.search(-1) is not None): + print("The value -1 exists") else: - print("The data -1 doesn't exist") + print("The value -1 doesn't exist") if(not t.empty()): - print(("Max Value: ", t.getMax().get_data())) - print(("Min Value: ", t.getMin().get_data())) + print("Max Value: ", t.get_max().value) + print("Min Value: ", t.get_min().value) for i in testlist: - t.delete(i) + t.remove(i) print(t) - - t.getNode(6) +二叉搜索树 = binary_search_tree if __name__ == "__main__": + import doctest + doctest.testmod() binary_search_tree() From e147f5c2961c9c4cdeaeacc0b3fc09d3217d468b Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Fri, 18 Oct 2019 23:53:37 +0800 Subject: [PATCH 4/9] Update binary_search_tree.py --- .../binary_tree/binary_search_tree.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 7359d4ebdf30..b8c5323f55fe 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -60,11 +60,11 @@ def __insert(self, value): Insert a new node in Binary Search Tree with value label """ new_node = Node(value, None) # Create a new Node - if self.empty(): # If Tree is empty - self.root = new_node # 则作为根节点 set its root - else: # If Tree is not empty - parent_node = self.root # from root - while True: # While we don't get to a leaf + if self.empty(): # If Tree is empty + self.root = new_node # set its root + else: # If Tree is not empty + parent_node = self.root # from root + while True: # While we don't get to a leaf if value < parent_node.value: # We go left if parent_node.left == None: parent_node.left = new_node # We insert the new node in a leaf @@ -86,10 +86,10 @@ def insert(self, *values): def search(self, value): if self.empty(): - raise IndexError("Warning: Tree is empty! please use another. ") # Warning: Tree is empty! please use another. + raise IndexError(" Warning: Tree is empty! please use another. ") else: node = self.root - while node is not None and node.value is not value: # Using lazy evaluation here to avoid NoneType Attribute error + while node is not None and node.value is not value: # using lazy evaluation here to avoid NoneType Attribute error if value < node.value: node = node.left else: @@ -130,13 +130,13 @@ def remove(self, value): elif(node.right is None): # Has only left children self.__reassign_nodes(node, node.left) else: - tmpNode = self.get_max(node.left) # Gets the max value of the left branch + tmpNode = self.get_max(node.left) # Gets the max value of the left branch self.remove(tmpNode.value) - node.value = tmpNode.value # Assigns the value to the node to delete and keesp tree structure + node.value = tmpNode.value # Assigns the value to the node to delete and keesp tree structure def preorder_traverse(self, node): if node is not None: - yield node # Preorder Traversal + yield node # 先根遍历 Preorder Traversal yield from self.preorder_traverse(node.left) yield from self.preorder_traverse(node.right) From fbe4f08953414b3eb12942d425edc1d550a14fbf Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Fri, 18 Oct 2019 23:55:51 +0800 Subject: [PATCH 5/9] Update binary_search_tree.py --- data_structures/binary_tree/binary_search_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index b8c5323f55fe..7446c46428ca 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -136,7 +136,7 @@ def remove(self, value): def preorder_traverse(self, node): if node is not None: - yield node # 先根遍历 Preorder Traversal + yield node # Preorder Traversal yield from self.preorder_traverse(node.left) yield from self.preorder_traverse(node.right) From ad9e8460235ed8f21f3bb409367ca2f3ffcc4245 Mon Sep 17 00:00:00 2001 From: Hocnonsense <48747984+Hocnonsense@users.noreply.github.com> Date: Sat, 19 Oct 2019 00:02:07 +0800 Subject: [PATCH 6/9] Update binary_search_tree.py --- data_structures/binary_tree/binary_search_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index 7446c46428ca..daab5cf9c62b 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -86,7 +86,7 @@ def insert(self, *values): def search(self, value): if self.empty(): - raise IndexError(" Warning: Tree is empty! please use another. ") + raise IndexError("Warning: Tree is empty! please use another. ") else: node = self.root while node is not None and node.value is not value: # using lazy evaluation here to avoid NoneType Attribute error From 8bc6629bf5a55187cde9efec437967e6f7beb5f7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 21 Dec 2019 01:29:36 +0100 Subject: [PATCH 7/9] Update binary_search_tree.py --- .../binary_tree/binary_search_tree.py | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index daab5cf9c62b..e090947938de 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -4,15 +4,15 @@ class Node: def __init__(self, value, parent): self.value = value + self.parent = parent # Added in order to delete a node easier self.left = None self.right = None - self.parent = parent # Added in order to delete a node easier def __repr__(self): from pprint import pformat if self.left is None and self.right is None: - return "'%s" % (self.value) + return str(self.value) return pformat( { "%s" @@ -27,16 +27,15 @@ def __init__(self, root = None): def __str__(self): """ - Return a string of all the Nodes. - In Order Traversal + Return a string of all the Nodes using in order traversal """ return str(self.root) def __reassign_nodes(self, node, newChildren): - if(newChildren is not None): # reset its kids + if(newChildren is not None): # reset its kids newChildren.parent = node.parent - if(node.parent is not None): # reset its parenst - if(self.is_right(node)): # If it is the Right Children + if(node.parent is not None): # reset its parent + if(self.is_right(node)): # If it is the right children node.parent.right = newChildren else: node.parent.left = newChildren @@ -44,30 +43,24 @@ def __reassign_nodes(self, node, newChildren): self.root = newChildren def is_right(self, node): - if(node == node.parent.right): - return True - else: - return False + return node == node.parent.right def empty(self): - if self.root is None: - return True - else: - return False + return self.root is None def __insert(self, value): """ Insert a new node in Binary Search Tree with value label """ - new_node = Node(value, None) # Create a new Node - if self.empty(): # If Tree is empty - self.root = new_node # set its root - else: # If Tree is not empty - parent_node = self.root # from root - while True: # While we don't get to a leaf - if value < parent_node.value: # We go left + new_node = Node(value, None) # create a new Node + if self.empty(): # if Tree is empty + self.root = new_node # set its root + else: # Tree is not empty + parent_node = self.root # from root + while True: # While we don't get to a leaf + if value < parent_node.value: # We go left if parent_node.left == None: - parent_node.left = new_node # We insert the new node in a leaf + parent_node.left = new_node # We insert the new node in a leaf break else: parent_node = parent_node.left @@ -89,20 +82,18 @@ def search(self, value): raise IndexError("Warning: Tree is empty! please use another. ") else: node = self.root - while node is not None and node.value is not value: # using lazy evaluation here to avoid NoneType Attribute error - if value < node.value: - node = node.left - else: - node = node.right + # use lazy evaluation here to avoid NoneType Attribute error + while node is not None and node.value is not value: + node = node.left if value < node.value else node.right return node def get_max(self, node = None): """ We go deep on the right branch """ - if(node is None): + if node is None: node = self.root - if(not self.empty()): + if not self.empty(): while(node.right is not None): node = node.right return node @@ -136,7 +127,7 @@ def remove(self, value): def preorder_traverse(self, node): if node is not None: - yield node # Preorder Traversal + yield node # Preorder Traversal yield from self.preorder_traverse(node.left) yield from self.preorder_traverse(node.right) @@ -171,9 +162,9 @@ def binary_search_tree(): 4 7 13 >>> t = BinarySearchTree().insert(8, 3, 6, 1, 10, 14, 13, 4, 7) - >>> print(" ".join([repr(i.value) for i in t.traversal_tree()])) + >>> print(" ".join(repr(i.value) for i in t.traversal_tree())) 8 3 1 6 4 7 10 14 13 - >>> print(" ".join([repr(i.value) for i in t.traversal_tree(postorder)])) + >>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder))) 1 4 7 6 3 13 14 10 8 >>> BinarySearchTree().search(6) Traceback (most recent call last): @@ -181,8 +172,7 @@ def binary_search_tree(): IndexError: Warning: Tree is empty! please use another. ''' t = BinarySearchTree() - testlist = [8, 3, 6, 1, 10, 14, 13, 4, 7] - for i in testlist: + for i in (8, 3, 6, 1, 10, 14, 13, 4, 7): t.insert(i) # Prints all the elements of the list in order traversal @@ -205,6 +195,7 @@ def binary_search_tree(): for i in testlist: t.remove(i) print(t) + 二叉搜索树 = binary_search_tree if __name__ == "__main__": From 4dc769c118f281f81a165dc6b9dc369a4a649b5b Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 21 Dec 2019 01:37:05 +0100 Subject: [PATCH 8/9] testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7) --- data_structures/binary_tree/binary_search_tree.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_structures/binary_tree/binary_search_tree.py b/data_structures/binary_tree/binary_search_tree.py index e090947938de..4c687379e8c8 100644 --- a/data_structures/binary_tree/binary_search_tree.py +++ b/data_structures/binary_tree/binary_search_tree.py @@ -171,8 +171,9 @@ def binary_search_tree(): ... IndexError: Warning: Tree is empty! please use another. ''' + testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7) t = BinarySearchTree() - for i in (8, 3, 6, 1, 10, 14, 13, 4, 7): + for i in testlist: t.insert(i) # Prints all the elements of the list in order traversal From 2286e048aad56ab6ebe88ce5dbc161837523eea0 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 21 Dec 2019 01:42:30 +0100 Subject: [PATCH 9/9] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index be227df1fdbd..25dca8b910b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ install: pip install -r requirements.txt before_script: - black --check . || true - flake8 . --count --select=E9,F4,F63,F7,F82 --show-source --statistics + - flake8 . --count --exit-zero --max-line-length=127 --statistics script: - scripts/validate_filenames.py # no uppercase, no spaces, in a directory - mypy --ignore-missing-imports .