Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added implementation for M-ary tree #140

Merged
merged 7 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions pydatastructs/trees/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from . import (
binary_trees,
m_ary_trees,
space_partitioning_trees,
heaps
)
Expand All @@ -15,6 +16,12 @@
)
__all__.extend(binary_trees.__all__)

from .m_ary_trees import (
MAryTreeNode, MAryTree
)

__all__.extend(m_ary_trees.__all__)

from .space_partitioning_trees import (
OneDimensionalSegmentTree
)
Expand Down
162 changes: 162 additions & 0 deletions pydatastructs/trees/m_ary_trees.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
from pydatastructs.utils import MAryTreeNode
from pydatastructs.linear_data_structures.arrays import ArrayForTrees

__all__ = [
'MAryTree'
]

class MAryTree(object):
"""
Abstract m-ary tree.

Parameters
==========

root_data
Optional, the root node of the binary tree.
If not of type MAryTreeNode, it will consider
root as data and a new root node will
be created.
key
Required if tree is to be instantiated with
root otherwise not needed.
comp: lambda
Optional, A lambda function which will be used
for comparison of keys. Should return a
bool value. By default it implements less
than operator.
is_order_statistic: bool
Set it to True, if you want to use the
order statistic features of the tree.
max_children
Optional, specifies the maximum number of children
a node can have. Defaults to 2 in case nothing is
specified.

References
==========

.. [1] https://en.wikipedia.org/wiki/M-ary_tree
"""

__slots__ = ['root_idx', 'max_children', 'comparator', 'tree', 'size',
'is_order_statistic']


def __new__(cls, key=None, root_data=None, comp=None,
is_order_statistic=False, max_children=2):
obj = object.__new__(cls)
if key is None and root_data is not None:
raise ValueError('Key required.')
key = None if root_data is None else key
root = MAryTreeNode(key, root_data)
root.is_root = True
obj.root_idx = 0
obj.max_children = max_children
obj.tree, obj.size = ArrayForTrees(MAryTreeNode, [root]), 1
obj.comparator = lambda key1, key2: key1 < key2 \
if comp is None else comp
obj.is_order_statistic = is_order_statistic
return obj

def insert(self, key, data):
"""
Inserts data by the passed key using iterative
algorithm.

Parameters
==========

key
The key for comparison.
data
The data to be inserted.

Returns
=======

None
"""
raise NotImplementedError("This is an abstract method.")

def delete(self, key, **kwargs):
"""
Deletes the data with the passed key
using iterative algorithm.

Parameters
==========

key
The key of the node which is
to be deleted.

Returns
=======

True
If the node is deleted successfully.
None
If the node to be deleted doesn't exists.

Note
====

The node is deleted means that the connection to that
node are removed but the it is still in tree.
"""
raise NotImplementedError("This is an abstract method.")

def search(self, key, **kwargs):
"""
Searches for the data in the binary search tree
using iterative algorithm.

Parameters
==========

key
The key for searching.
parent: bool
If true then returns index of the
parent of the node with the passed
key.
By default, False

Returns
=======

int
If the node with the passed key is
in the tree.
tuple
The index of the searched node and
the index of the parent of that node.
None
In all other cases.
"""
raise NotImplementedError("This is an abstract method.")

def to_binary_tree(self):
"""
Converts an m-ary tree to a binary tree.

Returns
=======

TreeNode
The root of the newly created binary tree.
"""
raise NotImplementedError("This is an abstract method.")


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.key, node.data)
for j in node.children:
if j is not None:
to_be_printed[i].append(j)
return str(to_be_printed)
1 change: 1 addition & 0 deletions pydatastructs/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from . import misc_util
from .misc_util import (
TreeNode,
MAryTreeNode,
LinkedListNode,
BinomialTreeNode,
AdjacencyListGraphNode,
Expand Down
44 changes: 44 additions & 0 deletions pydatastructs/utils/misc_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
__all__ = [
'TreeNode',
'MAryTreeNode',
'LinkedListNode',
'BinomialTreeNode',
'AdjacencyListGraphNode',
Expand Down Expand Up @@ -104,6 +105,49 @@ def __str__(self):
"""
return str((self.key, self.data))

class MAryTreeNode(TreeNode):
"""
Represents node in an M-ary trees.

Parameters
==========

data
Any valid data to be stored in the node.
key
Required for comparison operations.

Note
====

The following are the data members of the class:

children: DynamicOneDimensionalArray
An array of indices which stores the children of
this node in the M-ary tree array
is_root: bool, by default, False
If the current node is a root of the tree then
set it to True otherwise False.
"""
__slots__ = ['key', 'children', 'data', 'is_root']

def __new__(cls, key, data):
from pydatastructs.linear_data_structures.arrays import DynamicOneDimensionalArray
obj = Node.__new__(cls)
obj.data = data
obj.key = key
obj.is_root = False
obj.children = DynamicOneDimensionalArray(int, 0)
return obj

def add_children(self, *children):
"""
Adds children of current node.
"""
for child in children:
self.children.append(child)


class LinkedListNode(Node):
"""
Represents node in linked lists.
Expand Down