Imagine you have a row of lockers, each numbered and used to store similar items like books or files. This simple idea helps us understand arrays, one of the most fundamental data structures in programming. Arrays allow us to store multiple values of the same type in an organized way, making it easier to access, manage, and manipulate data efficiently.
In programming, data structures are essential because they help organize data so that operations like searching, inserting, or deleting can be done quickly and effectively. Without proper data structures, even simple tasks can become complicated and slow, especially when dealing with large amounts of data.
In this section, we will explore arrays and other important data structures, understand how they work, and learn how to perform basic operations on them. This knowledge is crucial for solving problems in competitive exams and real-world programming.
An array is a collection of elements, all of the same data type, stored in contiguous memory locations. This means that the elements are placed one after another in memory, like a row of lockers or seats in a theatre.
Arrays have two main characteristics:
Arrays can be classified based on their dimensions:
Each element in an array is identified by an index, which represents its position. In most programming languages, array indices start at 0. This means the first element is at index 0, the second at index 1, and so on.
For example, consider an array that stores the marks of 7 students in a test: [10, 20, 30, 40, 50, 60, 70]. The first student's marks are at index 0, the second at index 1, and so on.
Arrays are stored in contiguous memory locations, which means the memory addresses of elements are consecutive. This allows quick access to any element if we know its index.
Arrays support several basic operations that are essential for data manipulation:
Let's understand these operations step-by-step.
graph TD Start[Start] --> Init[Set index i = 0] Init --> CheckI{i < array size?} CheckI -- Yes --> Access[Access element at index i] Access --> Increment[Increment i by 1] Increment --> CheckI CheckI -- No --> End[End traversal] InsertStart[Start Insertion] --> CheckPos{Is position valid?} CheckPos -- No --> Error[Show error: Invalid position] CheckPos -- Yes --> Shift[Shift elements from end to position] Shift --> Insert[Insert new element at position] Insert --> EndInsert[End insertion]Traversal involves visiting each element from the first to the last. This is often done using a loop.
Insertion in an array requires shifting elements to the right from the insertion point to make space for the new element. Since arrays have fixed size, insertion is only possible if there is free space.
Deletion is the opposite of insertion: elements after the deleted element are shifted left to fill the gap.
Searching can be done by checking each element one by one (linear search) or by more efficient methods if the array is sorted.
Each of these operations has a time cost, called time complexity, which we will discuss later in the chapter.
Besides arrays, there are other important linear data structures that organize data in a sequence. These include:
Unlike arrays, linked lists do not store elements in contiguous memory locations. Instead, each element points to the next, allowing dynamic memory usage and easier insertion/deletion.
In the diagram above, the array stores elements in adjacent boxes, while the linked list stores data in nodes connected by pointers (arrows). This difference affects how data is accessed and modified.
Arrays are simple and fast for accessing elements by index, but have fixed size and costly insertions/deletions. Linked lists and other linear structures offer flexibility in size and easier insertions/deletions but require more memory and slower access.
Step 1: Start with the first element at index 0.
Step 2: Access the element at the current index and print it.
Step 3: Move to the next index by incrementing the index by 1.
Step 4: Repeat steps 2 and 3 until the last element (index 4) is printed.
Answer: The elements printed are 5, 10, 15, 20, 25 in order.
Step 1: Identify the insertion position (index 3).
Step 2: Shift elements from the last index (4) to index 3 one position to the right to make space.
Step 3: Place the new element 35 at index 3.
Step 4: The updated array is [10, 20, 30, 35, 40, 50].
graph TD Start[Start] --> CheckPos{Is index valid?} CheckPos -- No --> Error[Show error: Invalid index] CheckPos -- Yes --> Shift[Shift elements from end to index right by one] Shift --> Insert[Insert new element at index] Insert --> End[End]Step 1: Start at index 0, check if element is 40.
Step 2: If not, move to next index and repeat.
Step 3: At index 3, element is 40, so stop search.
Answer: Element 40 found at index 3.
Step 1: Initialize an empty stack with a top pointer set to -1.
Step 2: Push 10: increment top to 0, store 10 at index 0.
Step 3: Push 20: increment top to 1, store 20 at index 1.
Step 4: Push 30: increment top to 2, store 30 at index 2.
Step 5: Pop: remove element at top index 2 (30), decrement top to 1.
Answer: Stack after operations: [10, 20], top at index 1.
Searching:
Insertion:
Deletion:
| Operation | Best Case | Average Case | Worst Case |
|---|---|---|---|
| Searching | O(1) | O(n) | O(n) |
| Insertion | O(1) | O(n) | O(n) |
| Deletion | O(1) | O(n) | O(n) |
Arrays provide fast access by index but can be slow for insertions and deletions except at the end. Understanding time complexity helps in choosing the right data structure for a problem.
When to use: While accessing or iterating over arrays to avoid off-by-one errors
When to use: When searching efficiently in large datasets
When to use: To correctly insert elements without overwriting data
When to use: When learning new data structures or debugging code
When to use: To clarify logic and reduce syntax errors during exams
Progress tracking is paywalled — subscribe to mark subtopics as understood and save your streak.
Go to practice →