From 0b4514516bd61b9d23aad2f9921288a491735b35 Mon Sep 17 00:00:00 2001 From: Rahul Goswami Date: Sat, 24 Mar 2018 15:43:13 +0530 Subject: [PATCH] update README and some fixes --- CONTRIBUTING.md | 6 + README.md | 6 +- README_CN.md | 4 +- tree.md | 6 +- tree/rbtree/rbtree.py | 140 ++++++++++-------- .../segment_tree.py | 0 6 files changed, 95 insertions(+), 67 deletions(-) rename tree/{Segment_Tree => segment_tree}/segment_tree.py (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8bc7832a7..7661a84c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,6 +40,12 @@ Whenever you want a new algorithm to be added, or find some bugs in the existing just [submit an issue][newissue] and feel free to discuss over it. Or you may resolve any of the [existing issues][issues]. +## Collaborators +You can ask for any help or clarifications from the collaborators. +[Keon Kim](https://github.com/keon) +[Rahul Goswami](https://github.com/goswami-rahul) +[Ankit Agarwal](https://github.com/ankit167) + [fork]: https://help.github.com/articles/fork-a-repo/ [docstr]: https://www.python.org/dev/peps/pep-0257/#multi-line-docstrings [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html diff --git a/README.md b/README.md index df65941fd..aea00759a 100644 --- a/README.md +++ b/README.md @@ -200,8 +200,10 @@ Thanks for your interest in contributing! There are many ways to contribute to t - [serialize_deserialize](tree/bst/serialize_deserialize.py) - [successor](tree/bst/successor.py) - [unique_bst](tree/bst/unique_bst.py) - - [segment-tree](tree/Segment_Tree) - - [segment_tree](tree/Segment_Tree/segment_tree.py) + - [rbtree](tree/rbtree) + - [rbtree](tree/rbtree/rbtree.py) + - [segment_tree](tree/segment_tree) + - [segment_tree](tree/segment_tree/segment_tree.py) - [traversal](tree/traversal) - [inorder](tree/traversal/inorder.py) - [level_order](tree/traversal/level_order.py) diff --git a/README_CN.md b/README_CN.md index d211b02f2..3e1bb861e 100644 --- a/README_CN.md +++ b/README_CN.md @@ -171,8 +171,8 @@ python版数据结构和算法实现的简约版小示例 - [roman_to_int:罗马数转换整数](strings/roman_to_int.py) - [word_squares:单词平方](strings/word_squares.py) - [tree:树](tree) - - [segment-tree:线段树](tree/Segment_Tree) - - [segment_tree:线段树](tree/Segment_Tree/segment_tree.py) + - [segment-tree:线段树](tree/segment_tree) + - [segment_tree:线段树](tree/segment_tree/segment_tree.py) - [binary_tree_paths:二叉树路径](tree/binary_tree_paths.py) - [bintree2list:二叉树转换链表](tree/bintree2list.py) - [bst:二叉搜索树](tree/tree/bst) diff --git a/tree.md b/tree.md index 46bb00251..9f35af3e1 100644 --- a/tree.md +++ b/tree.md @@ -219,8 +219,10 @@ │   ├── path_sum2.py │   ├── path_sum.py │   ├── pretty_print.py +│   ├── rbtree +│   │   └── rbtree.py │   ├── same_tree.py -│   ├── Segment_Tree +│   ├── segment_tree │   │   └── segment_tree.py │   ├── traversal │   │   ├── inorder.py @@ -234,6 +236,6 @@ └── union-find └── count_islands.py -27 directories, 205 files +28 directories, 206 files ``` diff --git a/tree/rbtree/rbtree.py b/tree/rbtree/rbtree.py index 87ae0b1fc..15114e082 100644 --- a/tree/rbtree/rbtree.py +++ b/tree/rbtree/rbtree.py @@ -1,15 +1,23 @@ +""" +Implementation of Red-Black tree. +""" + + class RBNode: - def __init__(self, val,is_red,parent=None,left=None, right=None): + def __init__(self, val, is_red, parent=None, left=None, right=None): self.val = val self.parent = parent self.left = left self.right = right self.color = is_red + + class RBTree: def __init__(self): self.root = None + def left_rotate(self, node): - #set the node as the left child node of the current node's right node + # set the node as the left child node of the current node's right node right_node = node.right if right_node is None: return @@ -19,7 +27,7 @@ def left_rotate(self, node): if right_node.left is not None: right_node.left.parent = node right_node.parent = node.parent - #check the parent case + # check the parent case if node.parent is None: self.root = right_node elif node is node.parent.left: @@ -28,9 +36,10 @@ def left_rotate(self, node): node.parent.right = right_node right_node.left = node node.parent = right_node + def right_rotate(self, node): - #set the node as the right child node of the current node's left node - left_node = node.left + # set the node as the right child node of the current node's left node + left_node = node.left if left_node is None: return else: @@ -39,7 +48,7 @@ def right_rotate(self, node): if left_node.right is not None: left_node.right.parent = node left_node.parent = node.parent - #check the parent case + # check the parent case if node.parent is None: self.root = left_node elif node is node.parent.left: @@ -48,24 +57,25 @@ def right_rotate(self, node): node.parent.right = left_node left_node.right = node node.parent = left_node + def insert(self, node): - #the inserted node's color is default is red + # the inserted node's color is default is red root = self.root insert_node_parent = None - #find the position of inserted node + # find the position of inserted node while root is not None: insert_node_parent = root - if insert_node_parent.val node.val: - #case 2 not null and find left or right + # case 2 not null and find left or right insert_node_parent.left = node else: insert_node_parent.right = node @@ -74,60 +84,62 @@ def insert(self, node): node.color = 1 # fix the tree to self.fix_insert(node) + def fix_insert(self, node): - #case 1 the parent is null, then set the inserted node as root and color = 0 + # case 1 the parent is null, then set the inserted node as root and color = 0 if node.parent is None: node.color = 0 self.root = node - return - #case 2 the parent color is black, do nothing - #case 3 the parent color is red + return + # case 2 the parent color is black, do nothing + # case 3 the parent color is red while node.parent and node.parent.color is 1: if node.parent is node.parent.parent.left: uncle_node = node.parent.parent.right if uncle_node and uncle_node.color is 1: - #case 3.1 the uncle node is red - #then set parent and uncle color is black and grandparent is red - #then node => node.parent + # case 3.1 the uncle node is red + # then set parent and uncle color is black and grandparent is red + # then node => node.parent node.parent.color = 0 node.parent.parent.right.color = 0 node.parent.parent.color = 1 node = node.parent.parent - continue + continue elif node is node.parent.right: - #case 3.2 the uncle node is black or null, and the node is right of parent - #then set his parent node is current node - #left rotate the node and continue the next + # case 3.2 the uncle node is black or null, and the node is right of parent + # then set his parent node is current node + # left rotate the node and continue the next node = node.parent self.left_rotate(node) - #case 3.3 the uncle node is black and parent node is left - #then parent node set black and grandparent set red + # case 3.3 the uncle node is black and parent node is left + # then parent node set black and grandparent set red node.parent.color = 0 - node.parent.parent.color=1 + node.parent.parent.color = 1 self.right_rotate(node.parent.parent) else: uncle_node = node.parent.parent.left if uncle_node and uncle_node.color is 1: - #case 3.1 the uncle node is red - #then set parent and uncle color is black and grandparent is red - #then node => node.parent + # case 3.1 the uncle node is red + # then set parent and uncle color is black and grandparent is red + # then node => node.parent node.parent.color = 0 node.parent.parent.left.color = 0 node.parent.parent.color = 1 node = node.parent.parent - continue + continue elif node is node.parent.left: - #case 3.2 the uncle node is black or null, and the node is right of parent - #then set his parent node is current node - #left rotate the node and continue the next + # case 3.2 the uncle node is black or null, and the node is right of parent + # then set his parent node is current node + # left rotate the node and continue the next node = node.parent self.right_rotate(node) - #case 3.3 the uncle node is black and parent node is left - #then parent node set black and grandparent set red + # case 3.3 the uncle node is black and parent node is left + # then parent node set black and grandparent set red node.parent.color = 0 - node.parent.parent.color=1 + node.parent.parent.color = 1 self.left_rotate(node.parent.parent) self.root.color = 0 + def transplant(self, node_u, node_v): """ replace u with v @@ -144,7 +156,8 @@ def transplant(self, node_u, node_v): # check is node_v is None if node_v: node_v.parent = node_u.parent - def maximum(self,node): + + def maximum(self, node): """ find the max node when node regard as a root node :param node: @@ -154,17 +167,19 @@ def maximum(self,node): while temp_node.right is not None: temp_node = temp_node.right return temp_node - def minimum(self,node): + + def minimum(self, node): """ find the minimum node when node regard as a root node - :param node: + :param node: :return: minimum node """ temp_node = node while temp_node.left: temp_node = temp_node.left return temp_node - def delete(self,node): + + def delete(self, node): # find the node position node_color = node.color if node.left is None: @@ -172,7 +187,7 @@ def delete(self,node): self.transplant(node, node.right) elif node.right is None: temp_node = node.left - self.transplant( node, node.left) + self.transplant(node, node.left) else: # both child exits ,and find minimum child of right child node_min = self.minimum(node.right) @@ -187,37 +202,41 @@ def delete(self,node): node_min.left = node.left node_min.left.parent = node_min node_min.color = node.color - #when node is black ,then need to fix it with 4 cases + # when node is black ,then need to fix it with 4 cases if node_color == 0: self.delete_fixup(temp_node) def delete_fixup(self, node): # 4 cases while node != self.root and node.color == 0: - #node is not root and color is black + # node is not root and color is black if node == node.parent.left: # node is left node node_brother = node.parent.right - #case 1 node's red, can not get black node + + # case 1: node's red, can not get black node # set brother is black and parent is red if node_brother.color == 1: node_brother.color = 0 node.parent.color = 1 - self.left_rotate( node.parent) + self.left_rotate(node.parent) node_brother = node.parent.right - #case2:brothe node is black, and its children node is both black - if (node_brother.left is None or node_brother.left.color == 0) and \ - (node_brother.right is None or node_brother.right.color == 0): + + # case 2: brother node is black, and its children node is both black + if (node_brother.left is None or node_brother.left.color == 0) and ( + node_brother.right is None or node_brother.right.color == 0): node_brother.color = 1 node = node.parent else: - #case3 brother node is black , and its left child node is red and right is black + + # case 3: brother node is black , and its left child node is red and right is black if node_brother.right is None or node_brother.right.color == 0: node_brother.color = 1 node_brother.left.color = 0 self.right_rotate(node_brother) node_brother = node.parent.right - #case4 brother node is black, and right is red, and left is any color + + # case 4: brother node is black, and right is red, and left is any color node_brother.color = node.parent.color node.parent.color = 0 node_brother.right.color = 0 @@ -231,8 +250,8 @@ def delete_fixup(self, node): node.parent.color = 1 self.left_rotate(node.parent) node_brother = node.parent.right - if (node_brother.left is None or node_brother.left.color == 0) and \ - (node_brother.right is None or node_brother.right.color == 0): + if (node_brother.left is None or node_brother.left.color == 0) and ( + node_brother.right is None or node_brother.right.color == 0): node_brother.color = 1 node = node.parent else: @@ -260,17 +279,16 @@ def inorder(self): stack.append(root) root = root.left root = stack.pop() - res.append({'val':root.val,'color':root.color}) + res.append({'val': root.val, 'color': root.color}) root = root.right return res -if __name__=="__main__": + + +if __name__ == "__main__": rb = RBTree() - children = [11,2,14,1,7,15,5,8,4] + children = [11, 2, 14, 1, 7, 15, 5, 8, 4] for child in children: - node = RBNode(child,1) - print child - rb.insert(node) - print rb.inorder() - - - \ No newline at end of file + node = RBNode(child, 1) + print(child) + rb.insert(node) + print(rb.inorder()) diff --git a/tree/Segment_Tree/segment_tree.py b/tree/segment_tree/segment_tree.py similarity index 100% rename from tree/Segment_Tree/segment_tree.py rename to tree/segment_tree/segment_tree.py