Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
60a8458
Implemented CartesianTreeNode
Aimaanhasan Mar 30, 2020
b1daa60
Added CartesianTreeNode in __init__
Aimaanhasan Mar 30, 2020
16d8076
Implemented CartesianTree and Treap
Aimaanhasan Mar 30, 2020
d9b69b7
Added CartesianTree and Treap in __init__
Aimaanhasan Mar 30, 2020
596b4a3
Added suggestions
Aimaanhasan Mar 30, 2020
695d1e3
Updated reference as in suggestion
Aimaanhasan Mar 30, 2020
34520f1
Removed See Also on line 805 as suggested
Aimaanhasan Mar 30, 2020
bb96d0d
Removed line as suggested
Aimaanhasan Mar 30, 2020
29a81c5
Removed rotations from `CartesianTree`
Aimaanhasan Mar 30, 2020
91522f8
Updated as suggested in importing the nodes
Aimaanhasan Mar 30, 2020
3d0b1cd
Tests added
Aimaanhasan Apr 16, 2020
6a56115
Merge branch 'master' into Treaps
Aimaanhasan Apr 16, 2020
e6fafe6
Removed trailing white spaces
Aimaanhasan Apr 19, 2020
686cdb3
Removed trailing white spaces from test
Aimaanhasan Apr 19, 2020
3e0fa6a
Removed whitespace on line 308
Aimaanhasan Apr 19, 2020
8db5848
Replaced comparison by values with comparison by references in binary…
Aimaanhasan Apr 19, 2020
99c8c41
Removed reference by values in test_binary_trees.py
Aimaanhasan Apr 19, 2020
b62df25
Updated delete of `CartesianTree`
Aimaanhasan Apr 19, 2020
5b362c0
Updated docs
Aimaanhasan Apr 19, 2020
4e8a06f
Removed trailing spaces in misc_util.py
Aimaanhasan Apr 19, 2020
d9a8a79
Added CartesianTreeNode test
Aimaanhasan Apr 19, 2020
5b2a671
Imported CartesianTreeNode in test_misc_util.py
Aimaanhasan Apr 19, 2020
d97bd8c
As suggested #1
Aimaanhasan Apr 24, 2020
0471425
Added seed when calling random as suggested
Aimaanhasan Apr 24, 2020
27df682
As suggested to add space when defining `__slots__`
Aimaanhasan Apr 24, 2020
f1245a4
As suggested to add spaces between commas
Aimaanhasan Apr 24, 2020
59f2539
Made `data` an optional argument in both `CartesianTree` and `Treap`
Aimaanhasan Apr 24, 2020
5bfa2bb
Added spaces in commas in test
Aimaanhasan Apr 24, 2020
e7cbfb8
Updated docs according to the change in API
Aimaanhasan Apr 24, 2020
628ad51
Updated tests with the change in API
Aimaanhasan Apr 24, 2020
b475780
Assertion error fix
Aimaanhasan Apr 24, 2020
5b52087
Merge branch 'master' into Treaps
czgdp1807 Apr 24, 2020
d1a41c8
some minor changes
czgdp1807 Apr 24, 2020
5420313
some minor changes
czgdp1807 Apr 24, 2020
cd6852b
Apply suggestions from code review
czgdp1807 Apr 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pydatastructs/trees/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
BinarySearchTree,
BinaryTreeTraversal,
AVLTree,
BinaryIndexedTree
BinaryIndexedTree,
CartesianTree,
Treap
)
__all__.extend(binary_trees.__all__)

Expand Down
196 changes: 195 additions & 1 deletion pydatastructs/trees/binary_trees.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
from pydatastructs.utils import TreeNode
from pydatastructs.utils import CartesianTreeNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combine this import in line 1,

TreeNode, CartesianTreeNode

from pydatastructs.miscellaneous_data_structures import Stack
from pydatastructs.linear_data_structures import (
OneDimensionalArray, DynamicOneDimensionalArray)
from pydatastructs.linear_data_structures.arrays import ArrayForTrees
from collections import deque as Queue
import random

__all__ = [
'AVLTree',
'BinaryTree',
'BinarySearchTree',
'BinaryTreeTraversal',
'BinaryIndexedTree'
'BinaryIndexedTree',
'CartesianTree',
'Treap'
]

class BinaryTree(object):
Expand Down Expand Up @@ -623,7 +627,197 @@ def _left_rotate(self, j, k):
kp = self.tree[k].parent
if kp is None:
self.root_idx = k

class CartesianTree(SelfBalancingBinaryTree):

"""
Represents cartesian trees.

Examples
========

>>> from pydatastructs.trees import CartesianTree as CT
>>> c = CT()
>>> c.insert(1, 1, 4)
>>> c.insert(2, 2, 3)
>>> child = b.tree[b.root_idx].right
>>> c.tree[child].data
1
>>> c.search(1)
0
>>> c.search(-1) is None
True
>>> c.delete(1) is True
True
>>> c.search(1) is None
True
>>> c.delete(2) is True
True
>>> c.search(2) is None
True

References
==========

.. [1] https://www.cs.princeton.edu/courses/archive/spr09/cos423/Lectures/geo-st.pdf

See Also
========

pydatastructs.trees.binary_tree.SelfBalancingBinaryTree
"""

def _left_rotate(self, j, k):
y = self.tree[k].left
if y is not None:
self.tree[y].parent = j
self.tree[j].right = y
self.tree[k].parent = self.tree[j].parent
if self.tree[k].parent is not None:
if self.tree[self.tree[k].parent].left == j:
self.tree[self.tree[k].parent].left = k
else:
self.tree[self.tree[k].parent].right = k

self.tree[j].parent = k
self.tree[k].left = j
kp = self.tree[k].parent
if kp is None:
self.root_idx = k

def _right_rotate(self, j, k):
y = self.tree[k].right
if y is not None:
self.tree[y].parent = j
self.tree[j].left = y
self.tree[k].parent = self.tree[j].parent
if self.tree[k].parent is not None:
if self.tree[self.tree[k].parent].left == j:
self.tree[self.tree[k].parent].left = k
else:
self.tree[self.tree[k].parent].right = k
self.tree[j].parent = k
self.tree[k].right = j
kp = self.tree[k].parent
if kp is None:
self.root_idx = k

def _bubble_up(self, node_idx):
node = self.tree[node_idx]
parent_idx = self.tree[node_idx].parent
parent = self.tree[parent_idx]
while (node.parent != None) and (parent.priority > node.priority):
if parent.right == node_idx:
self._left_rotate(parent_idx, node_idx)

else:
self._right_rotate(parent_idx, node_idx)

node = self.tree[node_idx]
parent_idx = self.tree[node_idx].parent
if parent_idx != None:
parent = self.tree[parent_idx]
if node.parent == None:
self.tree[node_idx].is_root = True

def _trickle_down(self, node_idx):
node = self.tree[node_idx]
parent_idx = node.parent
while node.left != None or node.right != None:

if node.left == None:
self._left_rotate(node_idx, self.tree[node_idx].right)
elif node.right == None:
self._right_rotate(node_idx, self.tree[node_idx].left)
elif self.tree[node.left].priority < self.tree[node.right].priority:
self._right_rotate(node_idx, self.tree[node_idx].left)
else:
self._left_rotate(node_idx, self.tree[node_idx].right)

node = self.tree[node_idx]
parent_idx = node.parent


def insert(self, key, data, priority):
super(CartesianTree, self).insert(key, data)
node_idx = super(CartesianTree, self).search(key)
node = self.tree[node_idx]
new_node = CartesianTreeNode(key, priority, data)
new_node.parent = node.parent
new_node.left = node.left
new_node.right = node.right
self.tree[node_idx] = new_node
if node.is_root:
self.tree[node_idx].is_root = True
else:
self._bubble_up(node_idx)

def delete(self, key, **kwargs):
node_idx = super(CartesianTree, self).search(key)
if node_idx != None:
self._trickle_down(node_idx)
return super(CartesianTree, self).delete(key, balancing_info = True)
return None

def __str__(self):
to_be_printed = ['' for i in range(self.tree._last_pos_filled + 1)]
for i in range(self.tree._last_pos_filled + 1):
if self.tree[i] is not None:
node = self.tree[i]
to_be_printed[i] = (node.left, node.key, node.priority, node.data, node.right)
return str(to_be_printed)



class Treap(CartesianTree):

"""
Represents treaps.

Examples
========

>>> from pydatastructs.trees import Treap as T
>>> t = T()
>>> t.insert(1, 1)
>>> t.insert(2, 2)
>>> child = t.tree[b.root_idx].right
>>> t.tree[child].data
1
>>> t.search(1)
0
>>> t.search(-1) is None
True
>>> t.delete(1) is True
True
>>> t.search(1) is None
True
>>> t.delete(2) is True
True
>>> t.search(2) is None
True

References
==========

.. [1] https://en.wikipedia.org/wiki/Binary_search_tree

See Also
========

pydatastructs.trees.binary_tree.SelfBalancingBinaryTree
"""

priorities = set()

def insert(self, key, data):
priority = random.random()
while priority in self.priorities:
priority = random.random()
self.priorities.add(priority)
super(Treap, self).insert(key, data, priority)


class AVLTree(SelfBalancingBinaryTree):
"""
Represents AVL trees.
Expand Down
3 changes: 2 additions & 1 deletion pydatastructs/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
AdjacencyListGraphNode,
AdjacencyMatrixGraphNode,
GraphEdge,
Set
Set,
CartesianTreeNode
)
__all__.extend(misc_util.__all__)
33 changes: 32 additions & 1 deletion pydatastructs/utils/misc_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
'AdjacencyListGraphNode',
'AdjacencyMatrixGraphNode',
'GraphEdge',
'Set'
'Set',
'CartesianTreeNode'
]

_check_type = lambda a, t: isinstance(a, t)
Expand Down Expand Up @@ -52,6 +53,36 @@ def __str__(self):
"""
return str((self.left, self.key, self.data, self.right))

class CartesianTreeNode(TreeNode):
"""
Represents node in cartesian trees.

Parameters
==========

data
Any valid data to be stored in the node.
key
Required for comparison operations.
priority: int
An integer value for heap property.

"""
__slots__ = ['key', 'data', 'priotity']

def __new__(cls, key, priority, data=None):
obj = TreeNode.__new__(cls, key, data)
obj.priority = priority
return obj

def __str__(self):
"""
Used for printing.
"""
return str((self.left, self.key, self.priority, self.data, self.right))



Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

class BinomialTreeNode(TreeNode):
"""
Represents node in binomial trees.
Expand Down