Отсортировать элементы матрицы - Pascal
Формулировка задачи:
Дано натуральное N (1 ≤ N ≤ 10), целочисленный квадратный массив-матрица (aij), 0 ≤ i ,j < N. Отсортировать элементы матрицы так, чтобы при прохождении по схеме они были бы упорядочены по не убыванию. Методом быстрой рекурсивной сортировки.
Змейка из двух частей: вначале сверху вниз по строкам «вправо-влево» до побочной диагонали матрицы, потом снизу вверх по строкам «вправо-влево» от побочной диагонали матрицы.
Важное ограничение. При сортировке элементов матрицы не разрешается использовать дополнительные структуры данных (массивы), то есть вся сортировка должна производиться «на месте» – в исходном массиве. Кроме этого нужно сохранить временную сложность алгоритма сортировки: другими словами нельзя вводить дополнительных циклов (например, для вычисления координат) по сравнению с теми, что уже есть в сортировке.
0 1 2 3 6 5 4 15 7 8 14 13 9 10 11 12
Решение задачи: «Отсортировать элементы матрицы»
textual
Листинг программы
//глобальные константа и переменные: видны и в программе, и во всех подпрограммах const m = 10; //максимальный размеры массива var n, tn, gi, gj: integer; //размер массива, треугольное число, индексы массива a: array [0..m-1, 0..m-1] of integer; //массив //процедура генерации массива (можно при желании заменить процедурой ввода) procedure gen(n: integer); var i, j: integer; begin for i := 0 to n - 1 do for j := 0 to n - 1 do a[i, j] := -99 + random(199) end; //процедура печати массива, //параметры: s - заголовок, n - размер массива procedure prn(s: string; n: integer); var i, j: integer; begin writeln(s); for i := 0 to n - 1 do begin for j := 0 to n - 1 do write(a[i, j]: 4); writeln end end; //функция получения индексов массива, возвращает i, а также i и j в глобальных переменных //параметр: номер элемента в "хитрой змейке" //возвращаемые значения: i в gij и в gi, j в gj //например, a[gij(x), gj] // ^ ^ //сначала функция вычисляет i и j и возвращает i -+ | //теперь j (и i тоже) вычислены, можно использовать j ---+ function gij(k: integer): integer; var p, v: integer; //номер строки с треугольным числом, верхняя граница треугольника w: boolean; //флаг нижнего треугольника begin w := k >= tn; //определяем, который треугольник if w //если нижний треугольник then v := n * n //то граница - последний номер элемента else v := tn; //иначе граница - треугольное число p := v - 1 - k; //вычисляем номер строки gi := trunc(sqrt(1 + 8 * p) - 1) div 2; //индекс i gj := p - gi * (gi + 1) div 2; //индекс j if odd(n - gi) then gj := gi - gj; //коррекция gj для чётного n-1-i if w then gj := n - 1 - gj; //коррекция j для нижнего треугольника inc(gi); //общая коррекция i if not w then gi := n - gi; //коррекция i для верхнего треугольника gij := gi //сама функция возвращает i (а ещё дублирует i и помещает j в глобальные переменные gi и gj) end; //рекурсивная функция быстрой сортировки (она же - сортировка Хоара) //параметры: границы сортировки в виде номеров "хитрой змейки" procedure hoar(l, r: integer); var i, j, x, y: integer; //текущие границы в "хитрой змейке", середина этого интервала, буферная переменная begin i := l; //сохраняем текущие границы j := r; x := a[gij((l + r) div 2), gj]; //вычисляем середину repeat //цикл сортировки в пределах текущих границ while a[gij(i), gj] < x do inc(i); //если элемент нижней границы меньше элемента средней, то отсортировано, увеличиваем нижнюю границу while x < a[gij(j), gj] do dec(j); //если элемент верхней границы больше элемента средней, то отсортировано, уменьшаем верхнюю границу if i <= j //если индексы не пересеклись, then begin //то if a[gij(i), gj] > a[gij(j), gj] //если элементы на границах не в том порядке, then begin y := a[gij(j), gj]; //то меняем их местами a[gij(j), gj] := a[gij(i), gj]; a[gi, gj] := y end; inc(i); //увеличиваем границы, по-любому за границами уже отсортировано dec(j) end; until i >= j; //если границы встретились или поменялись местами, то сортировка текущего интекрвала закончена if l < j then hoar(l, j); //если j больше нижней границы, рекурсивный вызов сортировки интервала от нижней границы до j if i < r then hoar(i, r); //если i меньше нижней границы, рекурсивный вызов сортировки интервала от i до нижней границы end; begin randomize; //инициализация ГПСЧ repeat //ввод размера массива с проверкой write('n in [1..', m, ']; n = '); readln(n) until n in [1..m]; gen(n); //генерация массива prn('Исходный массив:', n); //печать исходного массива tn := n * (n + 1) div 2; //вычисление треугольного числа для последней строки массива hoar(0, n * n - 1); //сортировка массива prn('Отсортированный массив:', n); //вывод отсортированного массива readln end.
Объяснение кода листинга программы
- Объявляются глобальная константа
m
со значением 10, и глобальные переменныеn
,tn
,gi
,gj
типа целое число, иa
- массив целых чисел размеромm
наm
. - Происходит определение процедуры
gen
, которая инициализирует значения массиваa
случайными числами. - Определяется процедура
prn
для печати значений элементов массива. - Функция
gij
получает индексы массива по числуk
вхитрой змейке
. - Реализуется рекурсивная функция
hoar
для быстрой сортировки, с использованиемхитрой змейки
для доступа к элементам массива. - В основном блоке программы инициализируется генератор псевдослучайных чисел, происходит ввод размера массива, инициализация массива, печать исходного массива, вычисление треугольного числа и сортировка массива при помощи функции
hoar
, вывод отсортированного массива. Note: Последующий код приведен в языке Pascal.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д