Реверс массива (разворот на месте)

1. Задача: развернуть массив

Условие

Изменить порядок элементов массива на обратный без создания нового массива.

Пример

До:    [1, 2, 3, 4, 5]
После: [5, 4, 3, 2, 1]

2. Алгоритм

Идея: Менять местами элементы с противоположных концов, двигаясь к центру.

Шаги:

  1. Пройти до половины массива
  2. На каждой итерации поменять array[i] с array[opposite]
  3. opposite = len(array) - 1 - i — индекс с конца

3. Реализация

toReverse := [5]int{1, 2, 3, 4, 5}

for i := 0; i < len(toReverse)/2; i++ {
    opposite := len(toReverse) - 1 - i
    toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]
}

fmt.Printf("Результат: %v\n", toReverse)

Вывод:

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

4. Формула индекса opposite

opposite = len(array) - 1 - i

Примеры для массива из 5 элементов

len = 5

i=0: opposite = 5 - 1 - 0 = 4  // Первый ↔ Последний
i=1: opposite = 5 - 1 - 1 = 3  // Второй ↔ Предпоследний
i=2: opposite = 5 - 1 - 2 = 2  // Средний ↔ Сам с собой (не выполнится)

Почему -1? Индексация с 0 → последний индекс = len - 1.


5. Почему цикл до половины?

for i := 0; i < len(toReverse)/2; i++

Для массива из 5 элементов

len(toReverse) / 2 = 5 / 2 = 2  // Целочисленное деление

Итерации: i = 0, 1 (всего 2)

Что произойдёт, если i < len(array)?

i=0: меняем [0] ↔ [4]  ✓
i=1: меняем [1] ↔ [3]  ✓
i=2: меняем [2] ↔ [2]  (бесполезно)
i=3: меняем [3] ↔ [1]  ✗ Обратная замена!
i=4: меняем [4] ↔ [0]  ✗ Снова обратная замена!

Результат: Массив вернётся к исходному виду.


6. Пошаговая трассировка

Исходный массив

Индекс:  0  1  2  3  4
Массив: [1, 2, 3, 4, 5]

Итерация 0 (i=0)

opposite = 5 - 1 - 0 = 4

Меняем: array[0] ↔ array[4]
               1 ↔ 5

Результат: [5, 2, 3, 4, 1]

Итерация 1 (i=1)

opposite = 5 - 1 - 1 = 3

Меняем: array[1] ↔ array[3]
               2 ↔ 4

Результат: [5, 4, 3, 2, 1]

Условие цикла

i=2: 2 < 5/2?  → 2 < 2?  → НЕТ
Цикл завершён

Итог: [5, 4, 3, 2, 1]


7. Swap (обмен значений) в Go

Одновременное присваивание

a, b = b, a  // Go автоматически создаёт временную переменную

В контексте массива

array[i], array[opposite] = array[opposite], array[i]

Эквивалент на других языках:

temp := array[i]
array[i] = array[opposite]
array[opposite] = temp

8. Реверс для чётного количества элементов

Массив из 6 элементов

Индекс:  0  1  2  3  4  5
Массив: [1, 2, 3, 4, 5, 6]

len / 2 = 6 / 2 = 3

Итерации:

i=0: [0] ↔ [5]  →  [6, 2, 3, 4, 5, 1]
i=1: [1] ↔ [4]  →  [6, 5, 3, 4, 2, 1]
i=2: [2] ↔ [3]  →  [6, 5, 4, 3, 2, 1]

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


9. Отладка через debugger

Точка останова

for i := 0; i < len(toReverse)/2; i++ {
    opposite := len(toReverse) - 1 - i
    // ← breakpoint
    toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]
}

Что отслеживать

  1. i — текущий индекс с начала
  2. opposite — индекс с конца
  3. toReverse[i] — значение слева
  4. toReverse[opposite] — значение справа
  5. Массив после обмена

10. Варианты задачи

Реверс подмассива (с индекса start до end)

func reverseRange(arr []int, start, end int) {
    for start < end {
        arr[start], arr[end] = arr[end], arr[start]
        start++
        end--
    }
}

Проверка на палиндром

func isPalindrome(arr [5]int) bool {
    for i := 0; i < len(arr)/2; i++ {
        if arr[i] != arr[len(arr)-1-i] {
            return false
        }
    }
    return true
}

11. Типичные ошибки

Цикл до конца массива:

for i := 0; i < len(array); i++  // Массив вернётся в исходное состояние

Неправильная формула opposite:

opposite := len(array) - i  // Выход за границы!

Забыли swap:

toReverse[i] = toReverse[opposite]  // Потеря данных!

Правильно:

toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]

12. Итоги

✅ Реверс = обмен элементов с противоположных концов
✅ Цикл до половины: i < len/2
✅ Формула: opposite = len - 1 - i
✅ Swap в Go: a, b = b, a
✅ Работает для массивов чётной и нечётной длины

Паттерн:

for i := 0; i < len(array)/2; i++ {
    opposite := len(array) - 1 - i
    array[i], array[opposite] = array[opposite], array[i]
}

Практика: Разверните массив строк, реализуйте реверс без временной переменной, проверьте массив на симметричность.