Skip to main content

Overview

The UCX DSA package provides three array implementations with different characteristics:
  • Array: Fixed-capacity static array
  • DynamicArray: Automatically resizing array
  • CircularArray: Wrap-around circular buffer
All three implementations support index-based access using array[index] syntax and assignment with array[index] = value.

Array (Static)

A static array with a fixed capacity that must be specified at initialization.

Creating an Array

from dsa.array import Array

# Create array with default capacity of 10
arr = Array()
print(arr.capacity())  # 10
print(len(arr))        # 0

Key Methods

append(element)

Append an element to the end of the array.
arr = Array(capacity=5)
arr.append(1)
arr.append(2)
print(arr)  # [1, 2] Count: 2 Capacity: 5

# Raises Exception if capacity is exceeded
try:
    for i in range(10):
        arr.append(i)
except Exception as e:
    print(e)  # Capacity Error: Maximum capacity 5 reached.
Time Complexity: O(1)

extend(array)

Append multiple elements from an iterable.
arr = Array(capacity=10)
arr.extend([1, 2, 3])
arr.extend([4, 5])
print(arr.to_list())  # [1, 2, 3, 4, 5]

insert(index, element)

Insert an element at a specific index, shifting elements to the right.
arr = Array.from_list([1, 2, 4, 5])
arr.insert(2, 3)  # Insert 3 at index 2
print(arr.to_list())  # [1, 2, 3, 4, 5]
Time Complexity: O(n) - requires shifting elements

delete(index)

Delete an element at a specific index, shifting subsequent elements left.
arr = Array.from_list([1, 2, 3, 4, 5])
arr.delete(2)  # Delete element at index 2
print(arr.to_list())  # [1, 2, 4, 5]
Time Complexity: O(n) - requires shifting elements

Index Access

Retrieve and set elements using bracket notation.
arr = Array.from_list([10, 20, 30])

# Get element
print(arr[1])  # 20

# Set element
arr[1] = 25
print(arr[1])  # 25

# IndexError for out of bounds
try:
    value = arr[10]
except IndexError:
    print("Index out of bounds")
Time Complexity: O(1)

Utility Methods

arr = Array.from_list([1, 2, 3])

# Check if empty
print(arr.is_empty())  # False

# Get length
print(len(arr))  # 3

# Get capacity
print(arr.capacity())  # 3

# Convert to Python list
print(arr.to_list())  # [1, 2, 3]

DynamicArray

A dynamic array that automatically adjusts its capacity as needed. It doubles in size when full and halves when utilization drops below 25%.

Creating a DynamicArray

from dsa.array import DynamicArray

# Create with default capacity
arr = DynamicArray()

# Create with initial contents
arr = DynamicArray(contents=[1, 2, 3])

# Create from list
arr = DynamicArray.from_list([10, 20, 30])

Automatic Resizing

The DynamicArray grows and shrinks automatically:
arr = DynamicArray(capacity=2)
print(f"Initial capacity: {arr.capacity()}")  # 2

# Add elements - capacity doubles when full
arr.append(1)
arr.append(2)
print(f"After 2 elements: {arr.capacity()}")  # 2

arr.append(3)  # Triggers growth
print(f"After 3 elements: {arr.capacity()}")  # 4

arr.append(4)
arr.append(5)  # Triggers growth again
print(f"After 5 elements: {arr.capacity()}")  # 8

# Shrinks when count <= 1/4 of capacity
for i in range(4):
    arr.delete(0)
print(f"After deletions: {arr.capacity()}")  # 4 (shrunk from 8)
Growth Strategy:
  • Grows: capacity × 2 when count >= capacity
  • Shrinks: capacity ÷ 2 when count <= capacity ÷ 4
  • Minimum capacity: 10

Key Methods

DynamicArray supports all the same methods as Array:
arr = DynamicArray()

# Append without capacity concerns
for i in range(100):
    arr.append(i)
print(len(arr))  # 100

# Insert at any position
arr.insert(50, 999)

# Delete elements
arr.delete(0)

# Access elements
value = arr[10]
arr[10] = 42
Time Complexity:
  • append(): O(1) amortized
  • insert(): O(n)
  • delete(): O(n)
  • Index access: O(1)

CircularArray

A circular array implementation that wraps around when capacity is reached, overwriting the oldest elements.

Creating a CircularArray

from dsa.array import CircularArray

# Create with default capacity
circ = CircularArray(capacity=5)

# Create with initial contents
circ = CircularArray(contents=[1, 2, 3], capacity=5)

Circular Behavior

When the array is full, new elements overwrite the oldest ones:
circ = CircularArray(capacity=3)

# Add elements
circ.append(1)
circ.append(2)
circ.append(3)
print(circ.to_list())  # [1, 2, 3]

# Adding more wraps around and overwrites
circ.append(4)  # Overwrites 1
print(circ.to_list())  # [2, 3, 4]

circ.append(5)  # Overwrites 2
print(circ.to_list())  # [3, 4, 5]
CircularArray is perfect for fixed-size buffers like:
  • Recent history tracking
  • Rolling logs
  • Sliding window operations
  • Ring buffers

Key Methods

append(element)

Append element, wrapping around if necessary.
circ = CircularArray(capacity=3)
circ.extend([1, 2, 3])
circ.append(4)  # Wraps around
print(circ.to_list())  # [2, 3, 4]

insert(index, element)

Insert at index without wrapping (raises exception if full).
circ = CircularArray.from_list([1, 2, 3])
try:
    circ.insert(1, 99)
except Exception as e:
    print(e)  # Capacity Error: Maximum capacity 10 reached.

delete(index)

Delete element at index and shift remaining elements.
circ = CircularArray(contents=[1, 2, 3, 4, 5], capacity=5)
circ.delete(2)  # Delete element at index 2
print(circ.to_list())  # [1, 2, 4, 5]

raw_view()

View the underlying array structure.
circ = CircularArray(capacity=5)
circ.extend([1, 2, 3, 4, 5])
circ.append(6)  # Wraps around

print(circ.to_list())    # [2, 3, 4, 5, 6] (logical view)
print(circ.raw_view())   # [6, 2, 3, 4, 5] (physical memory)

Comparison

Use Array when:
  • You know the maximum size in advance
  • Fixed capacity is acceptable
  • Memory efficiency is critical
  • You want explicit capacity control
Example use case: Implementing a fixed-size cache or buffer

Common Operations

Equality Comparison

All array types support equality comparison based on contents:
from dsa.array import Array, DynamicArray, CircularArray

arr1 = Array.from_list([1, 2, 3])
arr2 = DynamicArray.from_list([1, 2, 3])
circ = CircularArray(contents=[1, 2, 3])

print(arr1 == arr2)   # True
print(arr1 == [1, 2, 3])  # False (different types)
CircularArray cannot be compared with Array or DynamicArray for equality.

String Representation

All arrays provide informative string representations:
arr = Array.from_list([1, 2, 3])
print(arr)  # [1, 2, 3] Count: 3 Capacity: 3

dyn = DynamicArray.from_list([4, 5])
print(dyn)  # [4, 5] Count: 2 Capacity: 10

circ = CircularArray(contents=[7, 8, 9], capacity=5)
print(circ)  # [7, 8, 9] Count: 3 Capacity: 5

Build docs developers (and LLMs) love