Lesson 2.1: Introduction to Data Structures
Data structures are the backbone of computer programming. They determine how data is organized, stored, and manipulated for efficient problem-solving.
๐ฆ What Are Data Structures?
- ๐ข Static Structures: Fixed-size containers like arrays
- ๐ Dynamic Structures: Expandable containers like linked lists
- ๐งฑ Linear Structures: Arrays, lists, stacks, and queues
- ๐ณ Hierarchical Structures: Trees, heaps
- ๐ Graph Structures: Represent connections like social networks
- โ๏ธ Hash-Based Structures: Key-value pairs for constant-time access
๐ Importance of Data Structures
- ๐ Optimize algorithm performance
- ๐ง Improve problem-solving and logical thinking
- โ๏ธ Enable reusable and scalable code
- ๐ Essential for databases, compilers, OS design, and more
- ๐ Help solve complex real-world problems more efficiently
- ๐ Used in file systems, networking, AI, and system design
๐งช Examples
// Example 1: Stack using array
int stack[100], top = -1;
void push(int val) {
stack[++top] = val;
}
// Example 2: Using a queue in Python
from collections import deque
queue = deque()
queue.append('A')
queue.append('B')
queue.popleft() # Removes 'A'
๐ Did you know? Choosing the wrong data structure can turn a fast program into a slow one!
๐ Key Takeaways (Lesson 2.1)
- Data structures define the structure and efficiency of a program.
- They are classified into linear, non-linear, static, and dynamic types.
- Mastering them is critical to cracking technical interviews.
- They're used everywhere: memory management, file systems, compilers, etc.
Lesson 2.2: Arrays
Arrays are fundamental data structures that store elements of the same type in contiguous memory locations.
๐ข Key Characteristics
- โก Fast random access (O(1)) via indexing
- ๐ Fixed size defined at creation
- ๐ Easy to traverse using loops
- ๐ง Used for static memory allocation
๐ ๏ธ Examples
// Example 1: Traversing an array
int arr[3] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
// Example 2: Array in Python
arr = [5, 10, 15, 20]
print(arr[2]) # Output: 15
โ
Pros
- Fast lookup by index
- Straightforward memory model
- Used in most low-level programming tasks
โ ๏ธ Cons
- Size is fixed; can't grow or shrink
- Insertion/deletion can be costly (O(n))
- Wasted memory if not fully utilized
๐ก Arrays are best when the number of elements is known in advance and random access is required.
๐ Key Takeaways (Lesson 2.2)
- Use arrays for fast, indexed data access
- They provide constant-time lookup but are static in size
- Efficient traversal and storage with a simple layout
Lesson 2.3: Linked Lists
Linked lists are dynamic data structures where each element (node) contains data and a reference to the next node in the sequence.
๐ Key Features
- Dynamic memory allocation โ size can grow/shrink at runtime
- Each node stores data and a pointer to the next node
- Supports efficient insertions and deletions
๐ ๏ธ Examples
// Example 1: Simple Node in C
struct Node {
int data;
struct Node* next;
};
# Example 2: Python implementation
class Node:
def __init__(self, data):
self.data = data
self.next = None
node1 = Node(5)
๐ Types of Linked Lists
- ๐ Singly Linked List (one pointer to next)
- โ๏ธ Doubly Linked List (pointers to next and previous)
- ๐ Circular Linked List (last node links to the first)
โ
Pros
- No predefined size
- Efficient insertion/deletion at the beginning or middle
- Great for implementing stacks, queues, graphs
โ ๏ธ Cons
- Sequential access only (no random indexing)
- Extra memory needed for pointers
- More complex traversal and manipulation
๐ง Linked lists are foundational for building more advanced structures like stacks, queues, graphs, and even hash tables.
๐ Key Takeaways (Lesson 2.3)
- Flexible, memory-efficient structure
- Ideal for dynamic data and when frequent insertions/deletions are needed
- Used in many real-world applications including memory management and OS design