ARRAYS
Quick links
Abstract Data Type (ADT)
An ADT is a blueprint or theoretical model of a data structure.
It defines:
1. What data is stored (the logical view).
2. What operations can be performed (like insert, delete, search, etc.).
It does not specify how the data is implemented in memory (that comes
later when you build the actual data structure).
Why ADT?
Before creating a data structure, we:
Write the requirements (what should the structure be able to do).
Plan the operations (like push/pop for Stack, enqueue/dequeue for Queue).
This acts as a contract between what users expect and how programmers
will implement it.
ADT = Requirements + Operations (Logical view)
Data Structure = Actual implementation (Physical view)
Array – Minimal Requirements (as an ADT)
1. Definition
An array is a collection of elements of the same data type,
Stored sequentially (contiguously) in memory,
Accessed directly using an index.
2. Characteristics / Requirements
Fixed size (cannot grow or shrink once declared).
Homogeneous elements (all of the same type: int, float, char, etc.).
ARRAYS 1
Random access possible → element at position i can be accessed in
O(1) time.
Indexed starting from 0 (in most programming languages).
3. Basic Operations (in ADT form)
Traverse → Access each element one by one.
Insert → Add an element at a given index (may require shifting
elements).
Delete → Remove an element at a given index (shifting again).
Search → Find the index of a given element.
Update → Change the value at a specific index.
In C/C++, the programmer must manage memory manually ( malloc , calloc ,
free ).
In Python, the memory manager + garbage collector handles allocation
and deal location automatically.
Array in Memory
1. Base Address
The address of the first element of the array.
All other elements are accessed by calculating offsets from the base.
Formula:
Address of arr[i] = Base Address + (i × size_of_each_element)
2. Total Size
Total memory reserved for the array.
Formula:
Total Size = Number of elements × Size of each element
3. Used Size
ARRAYS 2
Out of the total reserved size, how much is actually used by the program.
Example: Array of size 10 declared, but only 6 elements stored → Used size
= 6 × size_of_element.
4. In Python
Arrays are usually implemented as lists (dynamic).
arr = [10, 20, 30, 40, 50]
Base address: Hidden (managed by Python).
Total size: Dynamically managed (lists can grow).
Used size: Number of elements actually in the list.
Python doesn’t have fixed-size arrays by default. For C-style arrays:
import array
arr = [Link]('i', [10, 20, 30])
print(arr)
Static Array
A static array is an array whose size is fixed at compile time.
The memory is allocated before the program runs (compile time).
The size cannot be changed during execution.
Elements are stored contiguously in memory.
Characteristics of Static Array
1. Fixed size → cannot grow or shrink.
2. Stored in contiguous memory → allows direct indexing.
3. Base address + index formula →
Address(arr[i]) = Base Address + (i × size_of_element)
4. Fast access (O(1)) → direct access using index.
5. Insertion/Deletion is costly (O(n)) because shifting is required.
ARRAYS 3
Python lists are dynamic, but we can use the array module for a static-like
array:
import array
arr = [Link]('i', [10, 20, 30, 40, 50]) # static array of ints
print(arr[2]) # 30
Difference: Static Array vs Dynamic Array
Feature Static Array Dynamic Array (Python list / malloc in C)
Size Fixed at compile time Can grow or shrink at runtime
Contiguous, compile-
Memory Heap-allocated, runtime
time
Flexibility Not flexible Flexible
Example in C int arr[10]; int* arr = (int*) malloc(10*sizeof(int));
Operations on Array
1. Traversal in Array
Definition:
Visiting each element of the array exactly once to either display it, process
it, or perform some action.
Why Traversal?
To print all elements.
To perform computations (like sum, average).
To search or update values.
arr = [1, 2, 3, 4]
# Traversal
for element in arr:
print(element, end=" ")
Output:
ARRAYS 4
1234
Traversal visits every element → O(n)
2. Insertion in Array
Definition:
Insertion means adding a new element into the array at a particular
position/index.
Since arrays are stored in contiguous memory, insertion may require shifting
elements to make space.
Case 1: Insertion at the End
Simplest case (no shifting needed).
Just place the new element at the next available index.
Array = [10, 20, 30, _, _] (size = 5, used = 3)
Insert 40 at end
Result = [10, 20, 30, 40, _]
Case 2: Insertion at the Beginning
Insert at index 0 .
All elements must be shifted one step right.
Array = [10, 20, 30, _, _]
Insert 5 at index 0
Result = [5, 10, 20, 30, _]
Case 3: Insertion at a Specific Position (middle)
Insert at index k .
Elements from index k onward must be shifted right.
Example
ARRAYS 5
Array = [10, 20, 30, 40, _]
Insert 25 at index 2
Result = [10, 20, 25, 30, 40]
Example in Python
arr = [10, 20, 30, 40]
# Insert at index 2
[Link](2, 25)
print(arr)
At end → O(1) (best case)
At beginning or middle → O(n) (shifting required)
[Link] in Arrays
Definition:
Deletion means removing an element from an array at a given position.
Since arrays are stored in contiguous memory, we may need to shift elements
left to fill the gap.
Case 1: Deletion at the End
Just reduce the size by 1 (no shifting).
[10, 20, 30, 40]
Delete 40 → [10, 20, 30]
Case 2: Deletion at the Beginning
Remove first element, shift all elements left by one.
[10, 20, 30, 40]
Delete 10 → [20, 30, 40]
Case 3: Deletion at a Specific Position (Middle)
Remove element at index k , shift remaining elements left.
ARRAYS 6
[10, 20, 30, 40, 50]
Delete 30 → [10, 20, 40, 50]
# Example array
arr = [10, 20, 30, 40, 50]
print("Original Array:", arr)
# Case 1: Deletion at the End
[Link]() # removes last element
print("After deleting at the end:", arr)
# Case 2: Deletion at the Beginning
[Link](0) # removes first element
print("After deleting at the beginning:", arr)
# Case 3: Deletion at a Specific Position (Middle)
[Link](1) # removes element at index 1
print("After deleting at index 1:", arr)
# Case 4: Deletion by Value
[Link](40) # removes the first occurrence of value 40
print("After deleting value 40:", arr)
Feature Insertion Deletion
Operation Adds a new element Removes an existing element
Shifting Elements shifted right Elements shifted left
At End O(1) (direct placement) O(1) (reduce size)
O(n) (all elements shifted
At Beginning O(n) (all elements shifted right)
left)
O(n) (shift elements after
At Middle O(n) (shift elements after position)
position)
Space Requirement May require resizing if full No extra space needed
[Link] in Arrays
1. Linear Search
Definition: Check each element of the array one by one until the target
element is found (or end of array).
Works On: Both sorted and unsorted arrays.
ARRAYS 7
Time Complexity:
Best Case: O(1) (first element is target)
Worst Case: O(n) (last element or not found)
def linear_search(arr, target):
for i in range(len(arr)):
if arr[i] == target:
return i # return index if found
return -1 # not found
arr = [10, 20, 30, 40, 50]
print("Linear Search (30):", linear_search(arr, 30)) # Output: 2
print("Linear Search (99):", linear_search(arr, 99)) # Output: -1
2. Binary Search
Definition: Search by repeatedly dividing the array into halves until the
target is found.
Works On: Only sorted arrays.
Logic:
1. Compare middle element with target.
2. If equal → found.
3. If target < mid → search left half.
4. If target > mid → search right half.
Time Complexity:
Best Case: O(1)
Worst Case: O(log n)
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
ARRAYS 8
low = mid + 1
else:
high = mid - 1
return -1 # not found
arr = [10, 20, 30, 40, 50]
print("Binary Search (30):", binary_search(arr, 30)) # Output: 2
print("Binary Search (99):", binary_search(arr, 99)) # Output: -1
Binary Search vs Linear Search
Feature Linear Search Binary Search
Array Condition Works on any array Requires sorted array
Divide-and-conquer
Approach Sequential, element by element
(halving)
Time Complexity O(n) O(log n)
O(1) (middle element
Best Case O(1) (first element match)
match)
Worst Case O(n) O(log n)
Efficient for large sorted
Efficiency Inefficient for large datasets
arrays
[Link] in Arrays
Definition
Sorting means arranging elements of the array in a particular order (ascending
or descending).
1. Bubble Sort
Repeatedly swap adjacent elements if they are in the wrong order.
Time Complexity: O(n²)
Python Example (Bubble Sort):
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
ARRAYS 9
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j] # swap
arr = [64, 25, 12, 22, 11]
bubble_sort(arr)
print("Bubble Sort:", arr)
2. Selection Sort
Select the minimum element and place it in the correct position.
Time Complexity: O(n²)
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_idx = i
for j in range(i+1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i] # swap
arr = [64, 25, 12, 22, 11]
selection_sort(arr)
print("Selection Sort:", arr)
3. Insertion Sort
Insert each element into its correct place (like sorting cards in hand).
Time Complexity: O(n²)
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
ARRAYS 10
arr = [64, 25, 12, 22, 11]
insertion_sort(arr)
print("Insertion Sort:", arr)
4. Built-in Sorting (Python)
Python provides efficient built-in sorting using Timsort (O(n log n)).
arr = [64, 25, 12, 22, 11]
[Link]()
print("Built-in Sort:", arr)
Comparison of Sorting Algorithms
Algorithm Best Case Worst Case Stable Space
Bubble Sort O(n) O(n²) Yes O(1)
Selection Sort O(n²) O(n²) No O(1)
Insertion Sort O(n) O(n²) Yes O(1)
Python sort()
O(n) O(n log n) Yes O(n)
(Timsort)
[Link] in Arrays
Definition
Updating means modifying an existing element of the array at a given index.
Since arrays are stored in contiguous memory, update is directly possible
using index.
Time Complexity: O(1)
arr = [10, 20, 30, 40, 50]
print("Before Update:", arr)
arr[2] = 99 # Update element at index 2
print("After Update:", arr)
ARRAYS 11
2D Arrays
A 2D array is an array of arrays, where data is stored in rows and columns (like
a matrix).
1D array → [10, 20, 30]
2D array →
[
[1, 2, 3], # Row 0
[4, 5, 6], # Row 1
[7, 8, 9] # Row 2
]
Basic Requirements
Total size = rows × columns × size of each element
Accessing → arr[row][col]
Indexing starts from 0 (in Python, C, C++).
Declaration in Python
In Python, 2D arrays are usually represented using lists of lists.
# 2D Array (3x3 Matrix)
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print("Element at row 1, col 2:", arr[1][2]) # Output: 6
Traversal in 2D Array
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
ARRAYS 12
]
# Row-wise traversal
for i in range(len(arr)): # rows
for j in range(len(arr[0])): # columns
print(arr[i][j], end=" ")
print()
Output:
123
456
789
Insertion in 2D Array
arr = [[1, 2], [3, 4]]
arr[0].append(99) # Insert at row 0
print(arr) # [[1, 2, 99], [3, 4]]
Deletion in 2D Array
arr = [[1, 2, 3], [4, 5, 6]]
arr[0].remove(2) # Delete element 2 from row 0
print(arr) # [[1, 3], [4, 5, 6]]
Update in 2D Array
arr = [[1, 2, 3], [4, 5, 6]]
arr[1][2] = 99 # Update element at row 1, col 2
print(arr) # [[1, 2, 3], [4, 5, 99]]
Applications of 2D Arrays
Matrices (Math)
ARRAYS 13
Image Processing (pixels stored in 2D grid)
Game boards (chess, tic-tac-toe)
Tabular Data (rows & columns)
ARRAYS 14