Data Structures Arrays

Arrays

A linear data structure for storing elements.

Definition

An array is a data structure that stores a collection of items of the same type, such as integers or strings. These items are stored contiguously, much like a row of numbered lockers. Each item in an array can be quickly accessed using its index allowing for efficient retrieval and modification of data.

Operations

Arrays offer many operations that allow us to work with data efficiently. Because array elements are stored together in memory, some operations are very fast, while others require more work. The following table provides a comprehensive overview of array operations:

OperationsTimeSpace
AppendO(1)O(1)
PopO(1)O(1)
AccessO(1)O(1)
InsertO(n)O(1)
DeleteO(n)O(1)
SearchO(n)O(1)
Array Pointers

Pointers are crucial because they can be used to directly access and manipulate array elements. This direct access is what makes arrays efficient, especially when it comes to iterating over elements or implementing data structures like stacks and queues. Let's take a look at an example of pointers:

Reverse Array

def reverse(array: List[int]) -> List[int]:
    left, right = 0, len(array) - 1
    while left < right:
        array[left], array[right] = array[right], array[left]
        left += 1
        right -= 1
    return array

# Example usage
my_array = [1, 2, 3, 4, 5, 6]
print(reverse(my_array))  # Output: [6, 5, 4, 3, 2, 1]
Animation of two pointers being used to reverse the elements of an array

The code above defines a function reverse that takes an array of integers and reverses its elements in place, meaning the original array is modified without needing extra space for another array. It starts with two pointers, left at the beginning and right at the end of the array. The pointers meet in the middle to swap the elements, which reverses the original array.

Static Arrays

Static arrays have a fixed size, which is determined when the program is compiled. This makes them very quick for accessing elements. However, the fixed size has a drawback: you can't add more elements once the array is full. Trying to do so will cause an error or unexpected behavior. You don't need to worry about this in Python, but the concepts of static arrays are still important to know.

Dynamic Arrays

Unlike static arrays, dynamic arrays can change size while the program is running. However, the computer needs to do extra work to keep track of the array's size. Also, when the array gets bigger, it might need to be copied to a new location in memory. This process can take more time and use more resources compared to static arrays. Thankfully, clever resizing strategies makes this operation amortized constant time.

Dynamic Arrays

class DynamicArray:
    def __init__(self):
        self.array = [None]  # Start with an array of size 1
        self.size = 0

    def append(self, element):
        if self.size == len(self.array):
            # Array is full, time to resize
            new_array = [None] * (2 * len(self.array))
            # Copy elements to the new array
            for i in range(self.size):
                new_array[i] = self.array[i]
            self.array = new_array
            print(f"Array doubled. New capacity: {len(self.array)}")
        
        # Add the new element
        self.array[self.size] = element
        self.size += 1

# Example usage
dynamic_array = DynamicArray()
for i in range(5):
    dynamic_array.append(i)
    print(f"Added {i}. Current size: {dynamic_array.size}, Capacity: {len(dynamic_array.array)}")

Many programming languages have dynamic arrays built-in. For example, Python uses List, while Java has ArrayList. To use dynamic arrays effectively, it's important to be familiar with the array functions available in your preferred programming language.

Stacks

Stacks are data structures that follow the LIFO principle. While stacks are not arrays, they can be efficiently implemented using arrays. Stacks use arrays to their advantage by working with elements at the end. They have two key operations: push to add an item on top, and pop to remove the top item. This allows stacks to perform all operations in constant time.

OperationsTimeSpace
PushO(1)O(1)
PopO(1)O(1)
PeekO(1)O(1)
Is EmptyO(1)O(1)

The animation below demonstrates stack operations in Python. Remember, stacks are ideal for coding interviews when dealing with elements that depend on their predecessors.

Animation of stacks and the operations that they support
Best Practices

Understanding arrays and stacks is necessary for coding interviews and optimal problem-solving. These best practices will help you understand key concepts more easily, avoid common pitfalls, and approach problems with confidence:


Arrays are commonly used in sorting, searching, and iterating over data. Arrays are also the most common data structures for storing the final result of a problem. For this reason, you need to be comfortable with all the common functions and methods for arrays in your preferred language.

Copyright © StudyDSA. All rights reserved.