mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-02-04 03:17:34 +08:00
Updated README
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
arr = [10, 20, 30, 40]
|
||||
arr[1] = 30 # set element 1 (20) of array to 30
|
||||
print(arr)
|
||||
@@ -1,181 +0,0 @@
|
||||
"""
|
||||
An AVL tree
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
class Node:
|
||||
|
||||
def __init__(self, label):
|
||||
self.label = label
|
||||
self._parent = None
|
||||
self._left = None
|
||||
self._right = None
|
||||
self.height = 0
|
||||
|
||||
@property
|
||||
def right(self):
|
||||
return self._right
|
||||
|
||||
@right.setter
|
||||
def right(self, node):
|
||||
if node is not None:
|
||||
node._parent = self
|
||||
self._right = node
|
||||
|
||||
@property
|
||||
def left(self):
|
||||
return self._left
|
||||
|
||||
@left.setter
|
||||
def left(self, node):
|
||||
if node is not None:
|
||||
node._parent = self
|
||||
self._left = node
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
@parent.setter
|
||||
def parent(self, node):
|
||||
if node is not None:
|
||||
self._parent = node
|
||||
self.height = self.parent.height + 1
|
||||
else:
|
||||
self.height = 0
|
||||
|
||||
|
||||
class AVL:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
self.size = 0
|
||||
|
||||
def insert(self, value):
|
||||
node = Node(value)
|
||||
|
||||
if self.root is None:
|
||||
self.root = node
|
||||
self.root.height = 0
|
||||
self.size = 1
|
||||
else:
|
||||
# Same as Binary Tree
|
||||
dad_node = None
|
||||
curr_node = self.root
|
||||
|
||||
while True:
|
||||
if curr_node is not None:
|
||||
|
||||
dad_node = curr_node
|
||||
|
||||
if node.label < curr_node.label:
|
||||
curr_node = curr_node.left
|
||||
else:
|
||||
curr_node = curr_node.right
|
||||
else:
|
||||
node.height = dad_node.height
|
||||
dad_node.height += 1
|
||||
if node.label < dad_node.label:
|
||||
dad_node.left = node
|
||||
else:
|
||||
dad_node.right = node
|
||||
self.rebalance(node)
|
||||
self.size += 1
|
||||
break
|
||||
|
||||
def rebalance(self, node):
|
||||
n = node
|
||||
|
||||
while n is not None:
|
||||
height_right = n.height
|
||||
height_left = n.height
|
||||
|
||||
if n.right is not None:
|
||||
height_right = n.right.height
|
||||
|
||||
if n.left is not None:
|
||||
height_left = n.left.height
|
||||
|
||||
if abs(height_left - height_right) > 1:
|
||||
if height_left > height_right:
|
||||
left_child = n.left
|
||||
if left_child is not None:
|
||||
h_right = (left_child.right.height
|
||||
if (left_child.right is not None) else 0)
|
||||
h_left = (left_child.left.height
|
||||
if (left_child.left is not None) else 0)
|
||||
if (h_left > h_right):
|
||||
self.rotate_left(n)
|
||||
break
|
||||
else:
|
||||
self.double_rotate_right(n)
|
||||
break
|
||||
else:
|
||||
right_child = n.right
|
||||
if right_child is not None:
|
||||
h_right = (right_child.right.height
|
||||
if (right_child.right is not None) else 0)
|
||||
h_left = (right_child.left.height
|
||||
if (right_child.left is not None) else 0)
|
||||
if (h_left > h_right):
|
||||
self.double_rotate_left(n)
|
||||
break
|
||||
else:
|
||||
self.rotate_right(n)
|
||||
break
|
||||
n = n.parent
|
||||
|
||||
def rotate_left(self, node):
|
||||
aux = node.parent.label
|
||||
node.parent.label = node.label
|
||||
node.parent.right = Node(aux)
|
||||
node.parent.right.height = node.parent.height + 1
|
||||
node.parent.left = node.right
|
||||
|
||||
|
||||
def rotate_right(self, node):
|
||||
aux = node.parent.label
|
||||
node.parent.label = node.label
|
||||
node.parent.left = Node(aux)
|
||||
node.parent.left.height = node.parent.height + 1
|
||||
node.parent.right = node.right
|
||||
|
||||
def double_rotate_left(self, node):
|
||||
self.rotate_right(node.getRight().getRight())
|
||||
self.rotate_left(node)
|
||||
|
||||
def double_rotate_right(self, node):
|
||||
self.rotate_left(node.getLeft().getLeft())
|
||||
self.rotate_right(node)
|
||||
|
||||
def empty(self):
|
||||
if self.root is None:
|
||||
return True
|
||||
return False
|
||||
|
||||
def preShow(self, curr_node):
|
||||
if curr_node is not None:
|
||||
self.preShow(curr_node.left)
|
||||
print(curr_node.label, end=" ")
|
||||
self.preShow(curr_node.right)
|
||||
|
||||
def preorder(self, curr_node):
|
||||
if curr_node is not None:
|
||||
self.preShow(curr_node.left)
|
||||
self.preShow(curr_node.right)
|
||||
print(curr_node.label, end=" ")
|
||||
|
||||
def getRoot(self):
|
||||
return self.root
|
||||
|
||||
t = AVL()
|
||||
t.insert(1)
|
||||
t.insert(2)
|
||||
t.insert(3)
|
||||
# t.preShow(t.root)
|
||||
# print("\n")
|
||||
# t.insert(4)
|
||||
# t.insert(5)
|
||||
# t.preShow(t.root)
|
||||
# t.preorden(t.root)
|
||||
63
data_structures/binary_tree/basic_binary_tree.py
Normal file
63
data_structures/binary_tree/basic_binary_tree.py
Normal file
@@ -0,0 +1,63 @@
|
||||
class Node: # This is the Class Node with constructor that contains data variable to type data and left,right pointers.
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def display(tree): #In Order traversal of the tree
|
||||
|
||||
if tree is None:
|
||||
return
|
||||
|
||||
if tree.left is not None:
|
||||
display(tree.left)
|
||||
|
||||
print(tree.data)
|
||||
|
||||
if tree.right is not None:
|
||||
display(tree.right)
|
||||
|
||||
return
|
||||
|
||||
def depth_of_tree(tree): #This is the recursive function to find the depth of binary tree.
|
||||
if tree is None:
|
||||
return 0
|
||||
else:
|
||||
depth_l_tree = depth_of_tree(tree.left)
|
||||
depth_r_tree = depth_of_tree(tree.right)
|
||||
if depth_l_tree > depth_r_tree:
|
||||
return 1 + depth_l_tree
|
||||
else:
|
||||
return 1 + depth_r_tree
|
||||
|
||||
|
||||
def is_full_binary_tree(tree): # This functions returns that is it full binary tree or not?
|
||||
if tree is None:
|
||||
return True
|
||||
if (tree.left is None) and (tree.right is None):
|
||||
return True
|
||||
if (tree.left is not None) and (tree.right is not None):
|
||||
return (is_full_binary_tree(tree.left) and is_full_binary_tree(tree.right))
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def main(): # Main func for testing.
|
||||
tree = Node(1)
|
||||
tree.left = Node(2)
|
||||
tree.right = Node(3)
|
||||
tree.left.left = Node(4)
|
||||
tree.left.right = Node(5)
|
||||
tree.left.right.left = Node(6)
|
||||
tree.right.left = Node(7)
|
||||
tree.right.left.left = Node(8)
|
||||
tree.right.left.left.right = Node(9)
|
||||
|
||||
print(is_full_binary_tree(tree))
|
||||
print(depth_of_tree(tree))
|
||||
print("Tree is: ")
|
||||
display(tree)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,6 +0,0 @@
|
||||
from .hash_table import HashTable
|
||||
|
||||
class QuadraticProbing(HashTable):
|
||||
|
||||
def __init__(self):
|
||||
super(self.__class__, self).__init__()
|
||||
@@ -1,78 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from .union_find import UnionFind
|
||||
import unittest
|
||||
|
||||
|
||||
class TestUnionFind(unittest.TestCase):
|
||||
def test_init_with_valid_size(self):
|
||||
uf = UnionFind(5)
|
||||
self.assertEqual(uf.size, 5)
|
||||
|
||||
def test_init_with_invalid_size(self):
|
||||
with self.assertRaises(ValueError):
|
||||
uf = UnionFind(0)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
uf = UnionFind(-5)
|
||||
|
||||
def test_union_with_valid_values(self):
|
||||
uf = UnionFind(10)
|
||||
|
||||
for i in range(11):
|
||||
for j in range(11):
|
||||
uf.union(i, j)
|
||||
|
||||
def test_union_with_invalid_values(self):
|
||||
uf = UnionFind(10)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
uf.union(-1, 1)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
uf.union(11, 1)
|
||||
|
||||
def test_same_set_with_valid_values(self):
|
||||
uf = UnionFind(10)
|
||||
|
||||
for i in range(11):
|
||||
for j in range(11):
|
||||
if i == j:
|
||||
self.assertTrue(uf.same_set(i, j))
|
||||
else:
|
||||
self.assertFalse(uf.same_set(i, j))
|
||||
|
||||
uf.union(1, 2)
|
||||
self.assertTrue(uf.same_set(1, 2))
|
||||
|
||||
uf.union(3, 4)
|
||||
self.assertTrue(uf.same_set(3, 4))
|
||||
|
||||
self.assertFalse(uf.same_set(1, 3))
|
||||
self.assertFalse(uf.same_set(1, 4))
|
||||
self.assertFalse(uf.same_set(2, 3))
|
||||
self.assertFalse(uf.same_set(2, 4))
|
||||
|
||||
uf.union(1, 3)
|
||||
self.assertTrue(uf.same_set(1, 3))
|
||||
self.assertTrue(uf.same_set(1, 4))
|
||||
self.assertTrue(uf.same_set(2, 3))
|
||||
self.assertTrue(uf.same_set(2, 4))
|
||||
|
||||
uf.union(4, 10)
|
||||
self.assertTrue(uf.same_set(1, 10))
|
||||
self.assertTrue(uf.same_set(2, 10))
|
||||
self.assertTrue(uf.same_set(3, 10))
|
||||
self.assertTrue(uf.same_set(4, 10))
|
||||
|
||||
def test_same_set_with_invalid_values(self):
|
||||
uf = UnionFind(10)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
uf.same_set(-1, 1)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
uf.same_set(11, 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,87 +0,0 @@
|
||||
class UnionFind():
|
||||
"""
|
||||
https://en.wikipedia.org/wiki/Disjoint-set_data_structure
|
||||
|
||||
The union-find is a disjoint-set data structure
|
||||
|
||||
You can merge two sets and tell if one set belongs to
|
||||
another one.
|
||||
|
||||
It's used on the Kruskal Algorithm
|
||||
(https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
|
||||
|
||||
The elements are in range [0, size]
|
||||
"""
|
||||
def __init__(self, size):
|
||||
if size <= 0:
|
||||
raise ValueError("size should be greater than 0")
|
||||
|
||||
self.size = size
|
||||
|
||||
# The below plus 1 is because we are using elements
|
||||
# in range [0, size]. It makes more sense.
|
||||
|
||||
# Every set begins with only itself
|
||||
self.root = [i for i in range(size+1)]
|
||||
|
||||
# This is used for heuristic union by rank
|
||||
self.weight = [0 for i in range(size+1)]
|
||||
|
||||
def union(self, u, v):
|
||||
"""
|
||||
Union of the sets u and v.
|
||||
Complexity: log(n).
|
||||
Amortized complexity: < 5 (it's very fast).
|
||||
"""
|
||||
|
||||
self._validate_element_range(u, "u")
|
||||
self._validate_element_range(v, "v")
|
||||
|
||||
if u == v:
|
||||
return
|
||||
|
||||
# Using union by rank will guarantee the
|
||||
# log(n) complexity
|
||||
rootu = self._root(u)
|
||||
rootv = self._root(v)
|
||||
weight_u = self.weight[rootu]
|
||||
weight_v = self.weight[rootv]
|
||||
if weight_u >= weight_v:
|
||||
self.root[rootv] = rootu
|
||||
if weight_u == weight_v:
|
||||
self.weight[rootu] += 1
|
||||
else:
|
||||
self.root[rootu] = rootv
|
||||
|
||||
def same_set(self, u, v):
|
||||
"""
|
||||
Return true if the elements u and v belongs to
|
||||
the same set
|
||||
"""
|
||||
|
||||
self._validate_element_range(u, "u")
|
||||
self._validate_element_range(v, "v")
|
||||
|
||||
return self._root(u) == self._root(v)
|
||||
|
||||
def _root(self, u):
|
||||
"""
|
||||
Get the element set root.
|
||||
This uses the heuristic path compression
|
||||
See wikipedia article for more details.
|
||||
"""
|
||||
|
||||
if u != self.root[u]:
|
||||
self.root[u] = self._root(self.root[u])
|
||||
|
||||
return self.root[u]
|
||||
|
||||
def _validate_element_range(self, u, element_name):
|
||||
"""
|
||||
Raises ValueError if element is not in range
|
||||
"""
|
||||
if u < 0 or u > self.size:
|
||||
msg = ("element {0} with value {1} "
|
||||
"should be in range [0~{2}]")\
|
||||
.format(element_name, u, self.size)
|
||||
raise ValueError(msg)
|
||||
Reference in New Issue
Block a user