This repository has been archived by the owner on Apr 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from MGTheTrain/feature/data-structures
[Feature] - data structures
- Loading branch information
Showing
21 changed files
with
644 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
class TreeNode: | ||
def __init__(self, data): | ||
""" | ||
TreeNode class represents each element in the binary tree. | ||
""" | ||
self.data = data # Data stored in the node | ||
self.left = None # Reference to the left child node | ||
self.right = None # Reference to the right child node | ||
|
||
class BinaryTree: | ||
def __init__(self): | ||
""" | ||
BinaryTree class represents the binary tree data structure. | ||
""" | ||
self.root = None # Reference to the root node | ||
self.size = 0 # Number of elements in the tree | ||
|
||
def __len__(self): | ||
""" | ||
Returns the number of elements in the tree. | ||
""" | ||
return self.size | ||
|
||
def insert(self, data): | ||
""" | ||
Inserts an element into the binary tree. | ||
""" | ||
if self.root is None: | ||
self.root = TreeNode(data) | ||
else: | ||
self._insert_recursively(self.root, data) | ||
self.size += 1 | ||
|
||
def _insert_recursively(self, node, data): | ||
""" | ||
Helper method to recursively insert an element into the binary tree. | ||
""" | ||
if data < node.data: | ||
if node.left is None: | ||
node.left = TreeNode(data) | ||
else: | ||
self._insert_recursively(node.left, data) | ||
elif data > node.data: | ||
if node.right is None: | ||
node.right = TreeNode(data) | ||
else: | ||
self._insert_recursively(node.right, data) | ||
|
||
def _find_node(self, node, data): | ||
""" | ||
Helper method to find a node with the given data in the tree. | ||
""" | ||
if node is None or node.data == data: | ||
return node | ||
if data < node.data: | ||
return self._find_node(node.left, data) | ||
return self._find_node(node.right, data) | ||
|
||
def search(self, data): | ||
""" | ||
Searches for an element in the binary tree. | ||
""" | ||
node = self._find_node(self.root, data) | ||
return node is not None | ||
|
||
def _find_min(self, node): | ||
""" | ||
Helper method to find the minimum element in the binary tree. | ||
""" | ||
while node.left is not None: | ||
node = node.left | ||
return node | ||
|
||
def _delete_node(self, node, data): | ||
""" | ||
Helper method to delete a node with the given data from the binary tree. | ||
""" | ||
if node is None: | ||
return node | ||
|
||
if data < node.data: | ||
node.left = self._delete_node(node.left, data) | ||
elif data > node.data: | ||
node.right = self._delete_node(node.right, data) | ||
else: | ||
if node.left is None: | ||
return node.right | ||
elif node.right is None: | ||
return node.left | ||
temp = self._find_min(node.right) | ||
node.data = temp.data | ||
node.right = self._delete_node(node.right, temp.data) | ||
return node | ||
|
||
def remove(self, data): | ||
""" | ||
Removes an element from the binary tree. | ||
""" | ||
if not self.search(data): | ||
raise ValueError("Element not found in the tree") | ||
self.root = self._delete_node(self.root, data) | ||
self.size -= 1 | ||
|
||
def main(): | ||
""" | ||
Main entry point. | ||
""" | ||
bst = BinaryTree() | ||
bst.insert(5) | ||
bst.insert(3) | ||
bst.insert(7) | ||
bst.insert(2) | ||
bst.insert(4) | ||
bst.insert(6) | ||
bst.insert(8) | ||
|
||
print("Size of the binary tree: ", len(bst)) | ||
print("Is 4 present in the tree? ", bst.search(4)) | ||
bst.remove(4) | ||
print("Is 4 present in the tree after removal? ", bst.search(4)) | ||
print("Size of the binary tree after removal: ", len(bst)) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
class Node: | ||
def __init__(self, data): | ||
""" | ||
Node class represents each element in the doubly linked list. | ||
""" | ||
self.data = data # Data stored in the node | ||
self.prev = None # Reference to the previous node | ||
self.next = None # Reference to the next node | ||
|
||
class DoublyLinkedList: | ||
def __init__(self): | ||
""" | ||
DoublyLinkedList class represents the doubly linked list data structure. | ||
""" | ||
self.head = None # Reference to the head node | ||
self.tail = None # Reference to the tail node | ||
self.size = 0 # Number of elements in the list | ||
|
||
def __len__(self): | ||
""" | ||
Returns the number of elements in the list. | ||
""" | ||
return self.size | ||
|
||
def __getitem__(self, index): | ||
""" | ||
Returns the element at the specified index. | ||
""" | ||
if not 0 <= index < self.size: | ||
raise IndexError('Index out of bounds') | ||
current = self.head | ||
for _ in range(index): | ||
current = current.next | ||
return current.data | ||
|
||
def insert_at(self, index, item): | ||
""" | ||
Inserts an element at the specified index. | ||
""" | ||
if not 0 <= index <= self.size: | ||
raise IndexError('Index out of bounds') | ||
new_node = Node(item) | ||
if index == 0: | ||
# Insertion at the beginning | ||
new_node.next = self.head | ||
if self.head: | ||
self.head.prev = new_node | ||
self.head = new_node | ||
if self.tail is None: | ||
self.tail = new_node | ||
elif index == self.size: | ||
# Insertion at the end | ||
self.tail.next = new_node | ||
new_node.prev = self.tail | ||
self.tail = new_node | ||
else: | ||
# Insertion at a specific index | ||
current = self.head | ||
for _ in range(index - 1): | ||
current = current.next | ||
new_node.next = current.next | ||
current.next.prev = new_node | ||
current.next = new_node | ||
new_node.prev = current | ||
self.size += 1 | ||
|
||
def remove_at(self, index): | ||
""" | ||
Removes the element at the specified index. | ||
""" | ||
if not 0 <= index < self.size: | ||
raise IndexError('Index out of bounds') | ||
if index == 0: | ||
# Removal from the beginning | ||
if self.size == 1: | ||
# Special case: list has only one element | ||
self.head = None | ||
self.tail = None | ||
else: | ||
self.head = self.head.next | ||
self.head.prev = None | ||
elif index == self.size - 1: | ||
# Removal from the end | ||
self.tail = self.tail.prev | ||
self.tail.next = None | ||
else: | ||
# Removal from a specific index | ||
current = self.head | ||
for _ in range(index): | ||
current = current.next | ||
current.prev.next = current.next | ||
current.next.prev = current.prev | ||
self.size -= 1 | ||
|
||
def main(): | ||
""" | ||
Main entry point. | ||
""" | ||
dll = DoublyLinkedList() | ||
dll.insert_at(0, 1) | ||
dll.insert_at(1, 2) | ||
dll.insert_at(2, 3) # insertion between | ||
dll.insert_at(2, 5) # insertion between | ||
dll.insert_at(2, 7) # insertion between | ||
print("Length of the doubly linked list: ", len(dll)) | ||
print("Element at index 0: ", dll[0]) | ||
print("Element at index 1: ", dll[1]) | ||
print("Element at index 2: ", dll[2]) | ||
print("Element at index 3: ", dll[3]) | ||
print("Element at index 4: ", dll[4]) | ||
dll.remove_at(1) | ||
dll.remove_at(3) | ||
print("Length of the doubly linked list after removal: ", len(dll)) | ||
print("Element at index 0: ", dll[0]) | ||
print("Element at index 1: ", dll[1]) | ||
print("Element at index 1: ", dll[2]) | ||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.