Skip to content

Commit

Permalink
update README and some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
goswami-rahul committed Mar 24, 2018
1 parent 9787aae commit 0b45145
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 67 deletions.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -234,6 +236,6 @@
└── union-find
└── count_islands.py
27 directories, 205 files
28 directories, 206 files
```
140 changes: 79 additions & 61 deletions tree/rbtree/rbtree.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
if insert_node_parent.val < node.val:
root = root.right
else:
root = root.left
# set the n ode's parent node
node.parent = insert_node_parent
if insert_node_parent is None:
#case 1 inserted tree is null
# case 1 inserted tree is null
self.root = node
elif 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
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -154,25 +167,27 @@ 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:
temp_node = node.right
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)
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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()



node = RBNode(child, 1)
print(child)
rb.insert(node)
print(rb.inorder())
File renamed without changes.

0 comments on commit 0b45145

Please sign in to comment.