Data Structures - Array

Array is one of the most basic and commonly used data structures.

An array is a collection of elements of the same type stored contiguously in memory.


Array Definition and Memory Layout

In C, after an array is declared, a contiguous block of memory is allocated, and each element can be accessed directly by index.

数组内存布局示意图

The figure above shows the memory layout of an array containing 5 int elements. Assuming the starting address is 0x1000 and each int occupies 4 bytes, then:

  • arr[0]Located at address 0x1000
  • arr[1]Located at address 0x1004 (0x1000 + 4)
  • arr[i]Located at address 0x1000 + i × 4

It is precisely due to this contiguous storage characteristic that arrays can usestarting address + offsetto access any element in O(1) time.

One-Dimensional Array

Example

#include <stdio.h>

int main() {
    /* Declare and initialize a one-dimensional array */
    int arr[5] = {10, 20, 30, 40, 50};

    /* Traverse and access each element */
    printf("Array elements: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");  /* Output: Array elements: 10 20 30 40 50 */

    /* Direct access by index, time complexity O(1) */
    printf("arr[2] = %d\n", arr[2]);  /* Output: 30 */

    return 0;
}

Multidimensional Array

C supports multidimensional arrays, the most common being two-dimensional arrays, often used to represent tabular data such as matrices.

Two-dimensional arrays are still stored contiguously in memory by rows (row-major order), and are mapped to a two-dimensional view by calculating row and column indices.

Example

#include <stdio.h>

int main() {
    /* Declare a two-dimensional array with 3 rows and 4 columns */
    int matrix[3][4] = {
        {1,  2,  3,  4},
        {5,  6,  7,  8},
        {9, 10, 11, 12}
    };

    /* Traverse the two-dimensional array: outer loop iterates over rows, inner loop iterates over columns */
    printf("Two-dimensional array (3×4 matrix):\n");
    for (int i = 0; i < 3; i++) {        /* i is the row index */
        for (int j = 0; j < 4; j++) {    /* j is the column index */
            printf("%2d ", matrix[i][j]);
        }
        printf("\n");
    }

    /* Access a specific element: matrix[row][column] */
    printf("matrix[1][2] = %d\n", matrix[1][2]);  /* Output: 7 */
    return 0;
}

The memory address calculation formula for a two-dimensional array:元素地址 = 起始地址 + (i × 列数 + j) × sizeof(元素类型). Where i is the row index, and j is the column index.


Basic Operations of Arrays

数组插入和删除操作流程

The figure above shows the core steps of array insertion and deletion operations: for insertion, the elements after the target position need to be shifted backward one by one to make room; for deletion, the elements after the target position need to be shifted forward one by one to fill the gap.

Traversal

Example

#include <stdio.h>

/* Traverse and print all elements of the array Time complexity: O(n), where n is the array length */
"Traversal result: "

void traverse(int arr[], int n) {
    printf(/* Calculate the length of the array */);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {15, 28, 43, 56, 71};
    int n = sizeof(arr) / sizeof(arr[0]);  Insertion
    traverse(arr, n);
    return 0;
}

Insertion

Example

#include <stdio.h>

"Array is full, cannot insert
"Invalid insertion position
/* From back to front, shift the elements at pos and after it backward by one position */
/* Write data at the new position */
/* Increase the element count by 1 */

int insert(int arr[], int n, int pos, int value, int capacity) {
    if (n >= capacity) {
        printf(/* Capacity is 10, currently has 4 elements */\n");
        return -1;
    }
    if (pos < 0 || pos > n) {
        printf("Before insertion: "\n");
        return -1;
    }

    /* Output: Before insertion: 10 20 30 40 */
    for (int i = n; i > pos; i--) {
        arr[i] = arr[i - 1];
    }
    arr[pos] = value;  /* Write data to the new position */
    return n + 1;      /* Increase the number of elements by 1 */
}

int main() {
    int arr[10] = {10, 20, 30, 40};  /* Capacity is 10, currently there are 4 elements */
    int n = 4;

    printf(Before insertion:); for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");  /* Output: Before insertion: 10 20 30 40 */

    n = insert(arr, n, 2, 25, 10);  /* Insert 25 at index 2 */

    printf("After insertion: "); for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");  /* Output: After insertion: 10 20 25 30 40 */
    return 0;
}

Deletion

Example

#include <stdio.h>

/* Delete the element at a specified position in the array
Parameters: arr array, n current element count, pos deletion position (0-based)
Time complexity: O(n), worst case requires moving n elements
Return value: the number of elements after deletion */

int delete(int arr[], int n, int pos) {
    if (n <= 0) {
        printf("Array is empty, cannot delete\n");
        return 0;
    }
    if (pos < 0 || pos >= n) {
        printf("Invalid deletion position\n");
        return n;
    }

    /* From front to back, move the elements after pos forward by one position */
    for (int i = pos; i < n - 1; i++) {
        arr[i] = arr[i + 1];
    }
    return n - 1;  /* Decrease the element count by 1 */
}

int main() {
    int arr[10] = {10, 20, 30, 40, 50};
    int n = 5;

    printf("Before deletion: "); for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");  /* Output: Before deletion: 10 20 30 40 50 */

    n = delete(arr, n, 2);  /* Delete the element at index 2 (30) */

    printf("After deletion: "); for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");  /* Output: After deletion: 10 20 40 50 */
    return 0;
}

Search

To find a target value in an unordered array, the most straightforward method is to traverse the entire array and compare one by one, which is called linear search.

Example

#include <stdio.h>

/* Linear search: search for a target value in an array
Time complexity: O(n), worst case requires traversing the entire array
Return value: the index of the target element, returns -1 if not found */

int search(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) {
            return i;  /* Found, return the index */
        }
    }
    return -1;  /* Not found */
}

int main() {
    int arr[] = {43, 17, 89, 25, 61};
    int n = 5;

    int idx = search(arr, n, 89);
    if (idx != -1) {
        printf("Found target value 89, index is %d\n", idx);  /* Output: Found target value 89, index is 2 */
    } else {
        printf("Target value not found\n");
    }
    return 0;
}

Advantages and Disadvantages of Arrays

AdvantagesDescription
O(1) random accessAny element can be accessed in constant time via the index, which is the biggest advantage of arrays
Contiguous memoryContiguous storage facilitates CPU cache hits (spatial locality), improving access efficiency
Simple implementationIntuitive syntax, natively supported in most programming languages
DisadvantagesDescription
Fixed sizeStatic arrays in C are sized at compile time and cannot be dynamically resized
Slow insertion/deletionInserting or deleting elements in the middle of an array requires moving many elements, with a time complexity of O(n)
Space wasteIf the declared array is too large but the actual usage is small, it causes memory waste

It is precisely these limitations that give rise to the more flexible dynamic structure to be studied in the next chapter —Linked list。


Operation Complexity Summary

OperationTime complexityDescription
Access by indexO(1)Direct address calculation
Insert at the endO(1)No need to move elements
Insert at the head/middleO(n)Need to move subsequent elements
Delete the last elementO(1)No need to move elements
Delete the head/middle elementO(n)Need to move subsequent elements
Linear searchO(n)Compare one by one
Binary search (sorted array)O(log n)Requires the array to be sorted
Other extensions