### Learning journey ->

Let’s begin with the basics.

What are Data Structures?

Data structures are a way to organize and store data efficiently in a computer’s memory. They are fundamental building blocks in programming and are essential for tasks like searching, sorting, and managing data in various applications, including game development and website management.

• An array is a collection of elements of the same data type, stored in contiguous memory locations. It’s indexed by integers, making it easy to access elements by their position.

Example (in Python):

my_array = [1, 2, 3, 4, 5]

• A linked list is a linear data structure where elements (nodes) are connected through pointers. There are singly linked lists (each node points to the next) and doubly linked lists (each node points to both the next and the previous).

Example (in Python):

```class Node:
def __init__(self, data):
self.data = data
self.next = None

# Create nodes and establish links
node1 = Node(10)
node2 = Node(20)
node3 = Node(30)

node1.next = node2
node2.next = node3

# Display the original linked list
while current is not None:
print(current.data, end=" -> ")
current = current.next
print("None")

# Remove the element with value 20
current = node1
while current is not None:
if current.next and current.next.data == 20:
current.next = current.next.next
break
current = current.next

# Display the updated linked list

There’s a more efficient and generalized way to remove nodes from a linked list while preserving the integrity of the list.

To handle the case where the first, specific value and last node (tail) needs to be removed from a singly linked list, you can modify the `remove_node` function to account for this situation.

In this function:

1. We introduce a `prev` variable to keep track of the previous node while traversing the list.
2. When we find the node with the value to remove, we update the `next` pointer of the previous node (`prev.next`) to skip the node to be removed. This covers the case where the last node is the one to be removed.

`class Node:    def __init__(self, data):        self.data = data        self.next = None# Creating nodesnode1 = Node(10)node2 = Node(20)node3 = Node(30)node4 = Node(40)# Connecting nodesnode1.next = node2node2.next = node3node3.next = node4# Displaydef display_linked_list(head):    current = head    while current is not None:        print(current.data, end=" | ")        current = current.next    print("None")print("Original List")display_linked_list(node1)def remove_node(head, value_to_remove):    if head is None:        return None    # Handle the case where the first node needs to be removed    if head.data == value_to_remove:        return head.next    current = head    while current.next is not None:        if current.next.data == value_to_remove:            current.next = current.next.next            return head        prev = current  # Keep track of the previous node        current = current.next    # Handle the case where the last node needs to be removed    if current.data == value_to_remove:        prev.next = None    return head# Remove node with value 10node1 = remove_node(node1, 10)# Remove node with value 20node1 = remove_node(node1, 20)# Remove node with value 40node1 = remove_node(node1, 40)print("\nRemove List")display_linked_list(node1)# Append nodesnew_node = Node(55)current = node1while current.next is not None:    current = current.nextcurrent.next = new_nodenew_node = Node(88)current = node1while current.next is not None:    current = current.nextcurrent.next = new_nodeprint("\nAppend List")display_linked_list(node1)`
` `
• A stack is a linear data structure with a last-in, first-out (LIFO) order. It’s used for tasks like tracking function calls, parsing expressions, and undo operations.

Example (in Python):

my_stack = []
my_stack.append(1)
my_stack.append(2)
my_stack.append(3)
# Now the stack is [1, 2, 3]

===> Another example <===

`class Stack:    def __init__(self):        self.items = []    def is_empty(self):        return len(self.items) == 0    def push(self, item):        self.items.append(item)    def pop(self):        if not self.is_empty():            return self.items.pop()        else:            return "Stack is empty"    def peek(self):        if not self.is_empty():            return self.items[-1]        else:            return "Stack is empty"    def size(self):        return len(self.items)# Create a stackstack = Stack()# Push elements onto the stackstack.push(10)stack.push(20)stack.push(30)# Peek at the top elementtop_element = stack.peek()print(f"Top element: {top_element}")# Pop elements from the stackpopped_element = stack.pop()print(f"Popped element: {popped_element}")# Check if the stack is emptyprint(f"Is the stack empty? {stack.is_empty()}")# Get the size of the stackstack_size = stack.size()print(f"Stack size: {stack_size}")`

Output ===>>>
Top element: 30
Popped element: 30
Is the stack empty? False
Stack size: 2

———->

In this example:

We define a Stack class with push, pop, peek, size, and is_empty methods.
We create a stack, push elements onto it, peek at the top element, pop elements off it, check if it’s empty, and get its size.
The output will demonstrate the basic functionality of a stack. You’ll notice that the last element pushed (30) is the first one popped, confirming the Last-In, First-Out (LIFO) behavior of a stack.

• A queue is a linear data structure with a first-in, first-out (FIFO) order. It’s used for tasks like managing tasks in a printer queue or handling requests in a web server.

Example (in Python):

from collections import deque

my_queue = deque()
my_queue.append(1)
my_queue.append(2)
my_queue.append(3)
# Now the queue is [1, 2, 3]

• Trees are hierarchical data structures with a root node and child nodes. They are used in many algorithms and are the basis for more complex data structures like binary trees and heaps.

Example (a simple binary tree in Python):

class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None

root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)

These are some of the foundational data structures. Start by understanding how each works, how to perform basic operations on them (insertion, deletion, traversal), and when to use them in different scenarios.

Scroll to Top