Структурированные типы данных. Массивы

Информатика 11 класс · тест: 5 вопросов

Массивы — это фундаментальная структура данных, которая используется повсюду: от алгоритмов рекомендаций в YouTube до обработки пикселей в играх. Разберёмся, как устроен этот механизм, — на Си, Паскале и Python: у каждого примера есть вкладки, выбери свой язык.

Метафора массива: упорядоченное хранилище данных, где каждый элемент имеет свой адрес-индекс

Что такое массив и зачем он нужен?

Массив — это структура данных, представляющая собой упорядоченную коллекцию элементов одного типа, каждый из которых идентифицируется своим индексом (номером позиции).

💡 Зачем нужны массивы?

Представь, что тебе нужно обработать результаты 1000 студентов. Создавать 1000 отдельных переменных (score1, score2, ..., score1000) — абсурд. Массив позволяет хранить все данные под одним именем и обращаться к каждому элементу по индексу.

Объявление массива

Массив объявляется так:

тип_данных имя_массива[размер];
имя_массива: array[первый_индекс..последний_индекс] of тип;
имя_списка = [начальное_значение] * размер

Примеры объявления массивов:

int temperatures[365];      // массив из 365 целых чисел (температуры по дням года)
double prices[100];         // массив из 100 вещественных чисел (цены товаров)
char password[20];          // массив из 20 символов (пароль)
var
  temperatures: array[1..365] of integer;   { 365 целых чисел (температуры по дням года) }
  prices: array[1..100] of real;            { 100 вещественных чисел (цены товаров) }
  password: string[20];                     { строка до 20 символов (пароль) }
temperatures = [0] * 365     # 365 целых чисел (температуры по дням года)
prices = [0.0] * 100         # 100 вещественных чисел (цены товаров)
password = ""                # строка (пароль)

⚠️ Критически важно!

В Си и Python индексация массивов начинается с 0: первый элемент имеет индекс 0, второй — 1, и так далее; массив из 10 элементов имеет индексы от 0 до 9. В Паскале границы индексов задают при описании, обычно с 1: array[1..10] — индексы от 1 до 10. Поэтому в примерах на Паскале номера элементов на единицу больше.

Инициализация массива

Массив можно инициализировать при объявлении:

int scores[5] = {95, 87, 76, 92, 88};
double weights[] = {65.5, 72.3, 58.1};  // размер определяется автоматически
const
  scores: array[1..5] of integer = (95, 87, 76, 92, 88);
  weights: array[1..3] of real = (65.5, 72.3, 58.1);   { размер указывают явно }
scores = [95, 87, 76, 92, 88]
weights = [65.5, 72.3, 58.1]   # размер — len(weights)

Или заполнить в цикле:

int numbers[100];
for (int i = 0; i < 100; i++) {
    numbers[i] = i * 2;  // заполняем чётными числами
}
var
  numbers: array[1..100] of integer;
  i: integer;
...
for i := 1 to 100 do
  numbers[i] := (i - 1) * 2;   { заполняем чётными числами: 0, 2, 4, … }
numbers = [0] * 100
for i in range(100):
    numbers[i] = i * 2   # заполняем чётными числами

Основные операции с массивами

Рассмотрим базовые операции, которые выполняются с массивами в подавляющем большинстве задач.

Обработка массива: последовательный доступ к элементам через индексацию

Обработка массива: последовательный доступ к элементам через индексацию

Операция 1

📥 Ввод и вывод элементов

Пример: Ввод оценок студента и вывод в обратном порядке.

#include <stdio.h>

int main() {
    int grades[5];
    
    printf("Введите 5 оценок:\n");
    for (int i = 0; i < 5; i++) {
        printf("Оценка %d: ", i + 1);
        scanf("%d", &grades[i]);
    }
    
    printf("\nОценки в обратном порядке:\n");
    for (int i = 4; i >= 0; i--) {
        printf("%d ", grades[i]);
    }
    printf("\n");
    
    return 0;
}
program Grades;
var
  grades: array[1..5] of integer;
  i: integer;
begin
  writeln('Введите 5 оценок:');
  for i := 1 to 5 do
  begin
    write('Оценка ', i, ': ');
    readln(grades[i]);
  end;

  writeln;
  writeln('Оценки в обратном порядке:');
  for i := 5 downto 1 do
    write(grades[i], ' ');
  writeln;
end.
grades = [0] * 5

print("Введите 5 оценок:")
for i in range(5):
    grades[i] = int(input(f"Оценка {i + 1}: "))

print("\nОценки в обратном порядке:")
for i in range(4, -1, -1):
    print(grades[i], end=" ")
print()

Что происходит? Первый цикл for последовательно заполняет массив с индекса 0 до 4. Второй цикл выводит элементы в обратном порядке — с индекса 4 до 0.

Операция 2

🔍 Поиск элемента

Задача: Найти, есть ли в массиве заданное число.

Линейный поиск — самый простой алгоритм: последовательно проверяем каждый элемент.

#include <stdio.h>

int main() {
    int data[10] = {23, 45, 12, 67, 34, 89, 21, 56, 78, 90};
    int target, found = 0;
    
    printf("Введите число для поиска: ");
    scanf("%d", &target);
    
    for (int i = 0; i < 10; i++) {
        if (data[i] == target) {
            printf("Число %d найдено на позиции %d\n", target, i);
            found = 1;
            break;  // прерываем поиск
        }
    }
    
    if (!found) {
        printf("Число %d не найдено\n", target);
    }
    
    return 0;
}
program LinearSearch;
const
  data: array[1..10] of integer = (23, 45, 12, 67, 34, 89, 21, 56, 78, 90);
var
  target, i: integer;
  found: boolean;
begin
  write('Введите число для поиска: ');
  readln(target);
  found := false;

  for i := 1 to 10 do
    if data[i] = target then
    begin
      writeln('Число ', target, ' найдено на позиции ', i);
      found := true;
      break;   { прерываем поиск }
    end;

  if not found then
    writeln('Число ', target, ' не найдено');
end.
data = [23, 45, 12, 67, 34, 89, 21, 56, 78, 90]
target = int(input("Введите число для поиска: "))
found = False

for i in range(10):
    if data[i] == target:
        print(f"Число {target} найдено на позиции {i}")
        found = True
        break   # прерываем поиск

if not found:
    print(f"Число {target} не найдено")

Анализ сложности: В худшем случае (элемент в конце или отсутствует) нужно проверить все n элементов. Сложность: O(n) — линейная.

Операция 3

📊 Поиск максимума и минимума

Подход: Принимаем первый элемент за текущий максимум/минимум, затем сравниваем с ним все остальные элементы.

#include <stdio.h>

int main() {
    int numbers[8] = {42, 15, 73, 8, 91, 27, 64, 35};
    int max = numbers[0];
    int min = numbers[0];
    int max_index = 0;
    int min_index = 0;
    
    for (int i = 1; i < 8; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
            max_index = i;
        }
        if (numbers[i] < min) {
            min = numbers[i];
            min_index = i;
        }
    }
    
    printf("Максимум: %d (индекс %d)\n", max, max_index);
    printf("Минимум: %d (индекс %d)\n", min, min_index);
    
    return 0;
}
program MinMax;
const
  numbers: array[1..8] of integer = (42, 15, 73, 8, 91, 27, 64, 35);
var
  i, max, min, max_index, min_index: integer;
begin
  max := numbers[1];
  min := numbers[1];
  max_index := 1;
  min_index := 1;

  for i := 2 to 8 do
  begin
    if numbers[i] > max then
    begin
      max := numbers[i];
      max_index := i;
    end;
    if numbers[i] < min then
    begin
      min := numbers[i];
      min_index := i;
    end;
  end;

  writeln('Максимум: ', max, ' (индекс ', max_index, ')');
  writeln('Минимум: ', min, ' (индекс ', min_index, ')');
end.
numbers = [42, 15, 73, 8, 91, 27, 64, 35]
biggest = numbers[0]
smallest = numbers[0]
max_index = 0
min_index = 0

for i in range(1, 8):
    if numbers[i] > biggest:
        biggest = numbers[i]
        max_index = i
    if numbers[i] < smallest:
        smallest = numbers[i]
        min_index = i

print(f"Максимум: {biggest} (индекс {max_index})")
print(f"Минимум: {smallest} (индекс {min_index})")

Почему начинаем с i=1? Потому что numbers[0] уже стал начальным значением для max и min. Это классическая оптимизация.

Модификация массивов: вставка и удаление

Рассмотрим операции, которые изменяют структуру массива.

Операции вставки и удаления: реорганизация элементов массива

Операции вставки и удаления: реорганизация элементов массива

Удаление элемента

Задача: Удалить элемент с индексом k и сдвинуть все последующие элементы влево.

Логика: Элементы с индексами k+1, k+2, ..., n-1 перемещаются на позиции k, k+1, ..., n-2.

#include <stdio.h>

int main() {
    int arr[7] = {10, 20, 30, 40, 50, 60, 70};
    int n = 7;  // текущий размер массива
    int k = 3;  // индекс удаляемого элемента
    
    printf("Массив до удаления:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // Сдвигаем элементы влево
    for (int i = k; i < n - 1; i++) {
        arr[i] = arr[i + 1];
    }
    n--;  // уменьшаем размер
    
    printf("Массив после удаления элемента с индексом %d:\n", k);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}
program DeleteElement;
var
  arr: array[1..7] of integer;
  n, k, i: integer;
begin
  for i := 1 to 7 do
    arr[i] := i * 10;   { 10 20 30 40 50 60 70 }
  n := 7;   { текущий размер массива }
  k := 4;   { номер удаляемого элемента: в Паскале индексы с 1, это число 40 }

  writeln('Массив до удаления:');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;

  { сдвигаем элементы влево }
  for i := k to n - 1 do
    arr[i] := arr[i + 1];
  n := n - 1;   { уменьшаем размер }

  writeln('Массив после удаления элемента с индексом ', k, ':');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;
end.
arr = [10, 20, 30, 40, 50, 60, 70]
n = 7   # текущий размер массива
k = 3   # индекс удаляемого элемента

print("Массив до удаления:")
print(*arr[:n])

# сдвигаем элементы влево
for i in range(k, n - 1):
    arr[i] = arr[i + 1]
n = n - 1   # уменьшаем размер

print(f"Массив после удаления элемента с индексом {k}:")
print(*arr[:n])
# в Python то же самое делает готовая команда arr.pop(k)

Результат: 10 20 30 50 60 70 — элемент 40 (индекс 3) удалён.

Вставка элемента

Задача: Вставить новое значение на позицию с индексом k.

Логика: Элементы с индексами k, k+1, ..., n-1 сдвигаются вправо на позиции k+1, k+2, ..., n.

⚠️ Критично!

Сдвиг должен идти справа налево, иначе данные перезапишутся!

#include <stdio.h>

int main() {
    int arr[10] = {10, 20, 30, 40, 50, 60, 70};  // объявляем с запасом
    int n = 7;  // текущий размер
    int k = 3;  // позиция вставки
    int value = 35;  // вставляемое значение
    
    printf("Массив до вставки:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // Сдвигаем элементы вправо (ВАЖНО: справа налево!)
    for (int i = n; i > k; i--) {
        arr[i] = arr[i - 1];
    }
    arr[k] = value;
    n++;
    
    printf("Массив после вставки %d на позицию %d:\n", value, k);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}
program InsertElement;
var
  arr: array[1..10] of integer;   { объявляем с запасом }
  n, k, value, i: integer;
begin
  for i := 1 to 7 do
    arr[i] := i * 10;   { 10 20 30 40 50 60 70 }
  n := 7;       { текущий размер }
  k := 4;       { позиция вставки: в Паскале индексы с 1 }
  value := 35;  { вставляемое значение }

  writeln('Массив до вставки:');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;

  { сдвигаем элементы вправо (ВАЖНО: справа налево!) }
  for i := n + 1 downto k + 1 do
    arr[i] := arr[i - 1];
  arr[k] := value;
  n := n + 1;

  writeln('Массив после вставки ', value, ' на позицию ', k, ':');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;
end.
arr = [10, 20, 30, 40, 50, 60, 70, 0, 0, 0]   # с запасом
n = 7        # текущий размер
k = 3        # позиция вставки
value = 35   # вставляемое значение

print("Массив до вставки:")
print(*arr[:n])

# сдвигаем элементы вправо (ВАЖНО: справа налево!)
for i in range(n, k, -1):
    arr[i] = arr[i - 1]
arr[k] = value
n = n + 1

print(f"Массив после вставки {value} на позицию {k}:")
print(*arr[:n])
# в Python список растёт сам: то же делает arr.insert(k, value)

Результат: 10 20 30 35 40 50 60 70

Реверс массива

Задача: Перевернуть массив (первый элемент становится последним, и так далее).

Алгоритм: Меняем местами элементы с индексами i и n-1-i, где i идёт от 0 до n/2.

#include <stdio.h>

int main() {
    int arr[6] = {1, 2, 3, 4, 5, 6};
    int n = 6;
    
    printf("Исходный массив: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // Реверс
    for (int i = 0; i < n / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[n - 1 - i];
        arr[n - 1 - i] = temp;
    }
    
    printf("Перевёрнутый массив: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}
program ReverseArray;
const
  n = 6;
var
  arr: array[1..n] of integer;
  i, temp: integer;
begin
  for i := 1 to n do
    arr[i] := i;   { 1 2 3 4 5 6 }

  write('Исходный массив: ');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;

  { реверс }
  for i := 1 to n div 2 do
  begin
    temp := arr[i];
    arr[i] := arr[n + 1 - i];
    arr[n + 1 - i] := temp;
  end;

  write('Перевёрнутый массив: ');
  for i := 1 to n do
    write(arr[i], ' ');
  writeln;
end.
arr = [1, 2, 3, 4, 5, 6]
n = 6

print("Исходный массив:", *arr)

# реверс
for i in range(n // 2):
    temp = arr[i]
    arr[i] = arr[n - 1 - i]
    arr[n - 1 - i] = temp

print("Перевёрнутый массив:", *arr)

Результат: 6 5 4 3 2 1

💡 Почему n/2?

Если массив содержит 6 элементов, достаточно 3 обменов: (0↔5), (1↔4), (2↔3). Центральный элемент (если n нечётное) остаётся на месте автоматически.

Сортировка массивов

Зачем сортировать? Упорядоченные данные обрабатываются эффективнее. Например, двоичный поиск в отсортированном массиве имеет сложность O(log n) вместо O(n).

Сортировка: упорядочивание хаотичных данных в структурированную последовательность

Сортировка: упорядочивание хаотичных данных в структурированную последовательность

Алгоритм 1

💧 Сортировка пузырьком (Bubble Sort)

Принцип: Сравниваем соседние элементы и меняем их местами, если они в неправильном порядке. "Тяжёлые" элементы "тонут" вниз, "лёгкие" "всплывают" вверх.

#include <stdio.h>

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // Обмен элементов
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int data[6] = {64, 34, 25, 12, 22, 11};
    int n = 6;
    
    printf("До сортировки: ");
    for (int i = 0; i < n; i++) printf("%d ", data[i]);
    printf("\n");
    
    bubbleSort(data, n);
    
    printf("После сортировки: ");
    for (int i = 0; i < n; i++) printf("%d ", data[i]);
    printf("\n");
    
    return 0;
}
program BubbleSort;
type
  TArr = array[1..6] of integer;
var
  data: TArr;
  i: integer;

procedure bubbleSort(var arr: TArr; n: integer);
var
  i, j, temp: integer;
begin
  for i := 1 to n - 1 do
    for j := 1 to n - i do
      if arr[j] > arr[j + 1] then
      begin
        { обмен элементов }
        temp := arr[j];
        arr[j] := arr[j + 1];
        arr[j + 1] := temp;
      end;
end;

begin
  data[1] := 64; data[2] := 34; data[3] := 25;
  data[4] := 12; data[5] := 22; data[6] := 11;

  write('До сортировки: ');
  for i := 1 to 6 do write(data[i], ' ');
  writeln;

  bubbleSort(data, 6);

  write('После сортировки: ');
  for i := 1 to 6 do write(data[i], ' ');
  writeln;
end.
def bubble_sort(arr, n):
    for i in range(n - 1):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                # обмен элементов
                temp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = temp

data = [64, 34, 25, 12, 22, 11]
print("До сортировки:", *data)
bubble_sort(data, 6)
print("После сортировки:", *data)

Анализ:

  • Внешний цикл (i): n-1 проход
  • Внутренний цикл (j): на каждом проходе сравниваем всё меньше элементов
  • Сложность: O(n²) — квадратичная

Почему n-i-1? После каждого прохода самый большой элемент оказывается в конце, его больше не нужно проверять.

Алгоритм 2

🎯 Сортировка выбором (Selection Sort)

Принцип: Находим минимальный элемент в неотсортированной части массива и меняем его местами с первым неотсортированным элементом.

#include <stdio.h>

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int min_index = i;
        
        // Находим индекс минимального элемента
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[min_index]) {
                min_index = j;
            }
        }
        
        // Обмен
        if (min_index != i) {
            int temp = arr[i];
            arr[i] = arr[min_index];
            arr[min_index] = temp;
        }
    }
}

int main() {
    int data[6] = {64, 25, 12, 22, 11, 34};
    int n = 6;
    
    printf("До сортировки: ");
    for (int i = 0; i < n; i++) printf("%d ", data[i]);
    printf("\n");
    
    selectionSort(data, n);
    
    printf("После сортировки: ");
    for (int i = 0; i < n; i++) printf("%d ", data[i]);
    printf("\n");
    
    return 0;
}
program SelectionSort;
type
  TArr = array[1..6] of integer;
var
  data: TArr;
  i: integer;

procedure selectionSort(var arr: TArr; n: integer);
var
  i, j, min_index, temp: integer;
begin
  for i := 1 to n - 1 do
  begin
    min_index := i;

    { находим индекс минимального элемента }
    for j := i + 1 to n do
      if arr[j] < arr[min_index] then
        min_index := j;

    { обмен }
    if min_index <> i then
    begin
      temp := arr[i];
      arr[i] := arr[min_index];
      arr[min_index] := temp;
    end;
  end;
end;

begin
  data[1] := 64; data[2] := 25; data[3] := 12;
  data[4] := 22; data[5] := 11; data[6] := 34;

  write('До сортировки: ');
  for i := 1 to 6 do write(data[i], ' ');
  writeln;

  selectionSort(data, 6);

  write('После сортировки: ');
  for i := 1 to 6 do write(data[i], ' ');
  writeln;
end.
def selection_sort(arr, n):
    for i in range(n - 1):
        min_index = i

        # находим индекс минимального элемента
        for j in range(i + 1, n):
            if arr[j] < arr[min_index]:
                min_index = j

        # обмен
        if min_index != i:
            temp = arr[i]
            arr[i] = arr[min_index]
            arr[min_index] = temp

data = [64, 25, 12, 22, 11, 34]
print("До сортировки:", *data)
selection_sort(data, 6)
print("После сортировки:", *data)

Преимущество: Минимальное количество обменов — всего n-1. Полезно, когда операция обмена дорогая.

Сложность: O(n²) по сравнениям, O(n) по обменам.

Практическое применение: реальные задачи

Рассмотрим задачи, которые демонстрируют практическую ценность работы с массивами.

Эффективность алгоритмов: от линейного к логарифмическому поиску

Эффективность алгоритмов: от линейного к логарифмическому поиску

🌡️ Задача 1: Анализ метеоданных

Условие: Даны температуры за 30 дней июня. Найти среднюю температуру и дни с отклонением более чем на 5°C.

#include <stdio.h>

int main() {
    double temp[30];
    double sum = 0, avg;
    
    printf("Введите температуры за 30 дней июня:\n");
    for (int i = 0; i < 30; i++) {
        printf("День %d: ", i + 1);
        scanf("%lf", &temp[i]);
        sum += temp[i];
    }
    
    avg = sum / 30;
    printf("\nСредняя температура: %.2f°C\n", avg);
    
    printf("\nДни с отклонением >5°C от средней:\n");
    for (int i = 0; i < 30; i++) {
        double deviation = temp[i] - avg;
        if (deviation > 5 || deviation < -5) {
            printf("День %d: %.2f°C (отклонение: %+.2f°C)\n", 
                   i + 1, temp[i], deviation);
        }
    }
    
    return 0;
}
program JuneWeather;
var
  temp: array[1..30] of real;
  sum, avg, deviation: real;
  i: integer;
begin
  sum := 0;
  writeln('Введите температуры за 30 дней июня:');
  for i := 1 to 30 do
  begin
    write('День ', i, ': ');
    readln(temp[i]);
    sum := sum + temp[i];
  end;

  avg := sum / 30;
  writeln;
  writeln('Средняя температура: ', avg:0:2, '°C');

  writeln;
  writeln('Дни с отклонением >5°C от средней:');
  for i := 1 to 30 do
  begin
    deviation := temp[i] - avg;
    if (deviation > 5) or (deviation < -5) then
      writeln('День ', i, ': ', temp[i]:0:2, '°C (отклонение: ', deviation:0:2, '°C)');
  end;
end.
temp = [0.0] * 30
total = 0

print("Введите температуры за 30 дней июня:")
for i in range(30):
    temp[i] = float(input(f"День {i + 1}: "))
    total += temp[i]

avg = total / 30
print(f"\nСредняя температура: {avg:.2f}°C")

print("\nДни с отклонением >5°C от средней:")
for i in range(30):
    deviation = temp[i] - avg
    if deviation > 5 or deviation < -5:
        print(f"День {i + 1}: {temp[i]:.2f}°C (отклонение: {deviation:+.2f}°C)")

🔐 Задача 2: Криптографическая головоломка Буратино

Условие: Шифр замка — двузначное число. Сумма цифр + произведение цифр = само число. Найти все варианты.

Математический подход: Пусть число 10a + b, где a и b — цифры.
Условие: (a + b) + (a * b) = 10a + b
Упрощаем: a + a*b = 10a → a*b = 9a → b = 9 (при a ≠ 0)

#include <stdio.h>

int main() {
    printf("Возможные коды замка:\n");
    
    for (int num = 10; num <= 99; num++) {
        int a = num / 10;      // первая цифра
        int b = num % 10;      // вторая цифра
        
        if ((a + b) + (a * b) == num) {
            printf("%d ", num);
        }
    }
    printf("\n");
    
    return 0;
}
program LockCodes;
var
  num, a, b: integer;
begin
  writeln('Возможные коды замка:');
  for num := 10 to 99 do
  begin
    a := num div 10;   { первая цифра }
    b := num mod 10;   { вторая цифра }
    if (a + b) + (a * b) = num then
      write(num, ' ');
  end;
  writeln;
end.
print("Возможные коды замка:")
for num in range(10, 100):
    a = num // 10   # первая цифра
    b = num % 10    # вторая цифра
    if (a + b) + (a * b) == num:
        print(num, end=" ")
print()

Результат: 19, 29, 39, 49, 59, 69, 79, 89, 99

Проверка для 19: (1+9) + (1×9) = 10 + 9 = 19 ✓

✨ Ключевые выводы

Подведём итоги изученного материала.

Массивы — фундамент структур данных. Понимание массивов критически важно для изучения списков, стеков, очередей, деревьев. Индексация с 0 в Си — не каприз, а соглашение. Это связано с тем, как адресуется память на низком уровне. Алгоритмическая сложность имеет значение. Разница между O(n) и O(n²) может означать часы вычислений на больших данных. Простые алгоритмы — основа сложных. Сортировка пузырьком неэффективна для миллионов элементов, но её принцип лежит в основе более продвинутых методов. Массивы везде: обработка изображений (массив пикселей), аудио (массив сэмплов), игры (массив игровых объектов), машинное обучение (тензоры — многомерные массивы).

🤔 Проверь себя

Мини-кейсы для проверки понимания материала.

Мини-кейс 1: У тебя есть массив ID пользователей, вошедших в систему за последний час. Как быстро проверить, входил ли конкретный пользователь, если массив неотсортирован? Отсортирован?

Подумай о:

  • Какой алгоритм поиска использовать в неотсортированном массиве?
  • Можно ли ускорить поиск в отсортированном массиве?
  • Какова будет сложность каждого подхода?
Мини-кейс 2: В игре персонажи хранятся в массиве. При смерти персонажа его нужно удалить. Какая операция более эффективна: сдвиг всех элементов или просто пометка ячейки как "пустая"?

Рассмотри:

  • Сколько операций требует каждый подход?
  • Как это повлияет на обход массива?
  • Какие есть плюсы и минусы каждого метода?
Мини-кейс 3: Тебе нужно найти медиану (среднее значение при упорядочивании) массива из 1001 элемента. Какой первый шаг?

Подсказка:

  • Что нужно сделать с массивом перед поиском медианы?
  • На какой позиции будет находиться медиана после сортировки?
  • Нужно ли полностью сортировать массив?
Задача: Напиши функцию, которая проверяет, является ли массив палиндромом (читается одинаково слева направо и справа налево).

Алгоритм:

  • Сравнивай элементы с индексами i и n-1-i
  • Достаточно проверить до середины массива
  • Если хотя бы одна пара не совпадает — не палиндром

💻 Практические задания

Примени полученные знания на практике!

📝 Задание 1: Работа с температурами

Создай программу, которая:

  • Вводит температуры за неделю
  • Находит самую высокую и низкую температуру
  • Вычисляет среднюю температуру
  • Определяет, сколько дней было теплее/холоднее средней

🔢 Задание 2: Обработка чисел

Напиши программу, которая:

  • Заполняет массив из 20 случайных чисел от 1 до 100
  • Находит сумму чётных элементов
  • Подсчитывает количество элементов, кратных 3
  • Выводит элементы в обратном порядке

🎲 Задание 3: Анализ оценок

Разработай программу для анализа оценок класса:

  • Ввод оценок 10 учеников (от 2 до 5)
  • Подсчёт количества каждой оценки
  • Нахождение средней оценки класса
  • Определение количества отличников (5) и двоечников (2)

🔄 Задание 4: Циклический сдвиг

Реализуй программу циклического сдвига массива:

  • Создай массив из 8 элементов
  • Реализуй сдвиг всех элементов на 1 позицию вправо
  • Последний элемент должен стать первым
  • Например: {1,2,3,4,5} → {5,1,2,3,4}
Массивы — мышление в терминах коллекций данных

Массивы — мышление в терминах коллекций данных

🚀 Отличная работа! Массивы — это не просто учебная тема. Это мышление в терминах коллекций данных, понимание того, как компьютер организует и обрабатывает информацию в памяти. Освоив массивы, ты делаешь шаг к пониманию алгоритмов, которые меняют мир — от поисковых систем до искусственного интеллекта.

Проверь себя

5 случайных вопросов по этому уроку — при следующем открытии будут другие. Ответы проверяются сразу, без регистрации.