Отсортировать элементы матрицы - Pascal

Узнай цену своей работы

Формулировка задачи:

Дано натуральное N (1 ≤ N ≤ 10), целочисленный квадратный массив-матрица (aij), 0 ≤ i ,j < N. Отсортировать элементы матрицы так, чтобы при прохождении по схеме они были бы упорядочены по не убыванию. Методом быстрой рекурсивной сортировки.
Листинг программы
  1. 0 1 2 3
  2. 6 5 4 15
  3. 7 8 14 13
  4. 9 10 11 12
Змейка из двух частей: вначале сверху вниз по строкам «вправо-влево» до побочной диагонали матрицы, потом снизу вверх по строкам «вправо-влево» от побочной диагонали матрицы. Важное ограничение. При сортировке элементов матрицы не разрешается использовать дополнительные структуры данных (массивы), то есть вся сортировка должна производиться «на месте» – в исходном массиве. Кроме этого нужно сохранить временную сложность алгоритма сортировки: другими словами нельзя вводить дополнительных циклов (например, для вычисления координат) по сравнению с теми, что уже есть в сортировке.

Решение задачи: «Отсортировать элементы матрицы»

textual
Листинг программы
  1. //глобальные константа и переменные: видны и в программе, и во всех подпрограммах
  2. const m = 10; //максимальный размеры массива
  3. var n, tn, gi, gj: integer; //размер массива, треугольное число, индексы массива
  4.     a: array [0..m-1, 0..m-1] of integer; //массив
  5.  
  6. //процедура генерации массива (можно при желании заменить процедурой ввода)
  7. procedure gen(n: integer);
  8. var i, j: integer;
  9. begin
  10.   for i := 0 to n - 1 do
  11.     for j := 0 to n - 1 do a[i, j] := -99 + random(199)
  12. end;
  13.  
  14. //процедура печати массива,
  15. //параметры: s - заголовок, n - размер массива
  16. procedure prn(s: string; n: integer);
  17. var i, j: integer;
  18. begin
  19.   writeln(s);
  20.   for i := 0 to n - 1 do
  21.     begin
  22.       for j := 0 to n - 1 do write(a[i, j]: 4);
  23.       writeln
  24.     end
  25. end;
  26.  
  27. //функция получения индексов массива, возвращает i, а также i и j в глобальных переменных
  28. //параметр: номер элемента в "хитрой змейке"
  29. //возвращаемые значения: i в gij и в gi, j в gj
  30. //например,                                    a[gij(x), gj]
  31. //                                                ^      ^
  32. //сначала функция вычисляет i и j и возвращает i -+      |
  33. //теперь j (и i тоже) вычислены, можно использовать j ---+
  34. function gij(k: integer): integer;
  35. var p, v: integer; //номер строки с треугольным числом, верхняя граница треугольника
  36.     w: boolean; //флаг нижнего треугольника
  37. begin
  38.   w := k >= tn; //определяем, который треугольник
  39.   if w //если нижний треугольник
  40.     then v := n * n //то граница - последний номер элемента
  41.     else v := tn; //иначе граница - треугольное число
  42.   p := v - 1 - k; //вычисляем номер строки
  43.   gi := trunc(sqrt(1 + 8 * p) - 1) div 2; //индекс i
  44.   gj := p - gi * (gi + 1) div 2; //индекс j
  45.   if odd(n - gi) then gj := gi - gj; //коррекция gj для чётного n-1-i
  46.   if w then gj := n - 1 - gj; //коррекция j для нижнего треугольника
  47.   inc(gi); //общая коррекция i
  48.   if not w then gi := n - gi; //коррекция i для верхнего треугольника
  49.   gij := gi //сама функция возвращает i (а ещё дублирует i и помещает j в глобальные переменные gi и gj)
  50. end;
  51.  
  52. //рекурсивная функция быстрой сортировки (она же - сортировка Хоара)
  53. //параметры: границы сортировки в виде номеров "хитрой змейки"
  54. procedure hoar(l, r: integer);
  55. var i, j, x, y: integer; //текущие границы в "хитрой змейке", середина этого интервала, буферная переменная
  56. begin
  57.   i := l; //сохраняем текущие границы
  58.   j := r;
  59.   x := a[gij((l + r) div 2), gj]; //вычисляем середину
  60.   repeat //цикл сортировки в пределах текущих границ
  61.     while a[gij(i), gj] < x do inc(i); //если элемент нижней границы меньше элемента средней, то отсортировано, увеличиваем нижнюю границу
  62.     while x < a[gij(j), gj] do dec(j); //если элемент верхней границы больше элемента средней, то отсортировано, уменьшаем верхнюю границу
  63.     if i <= j //если индексы не пересеклись,
  64.       then begin //то
  65.         if a[gij(i), gj] > a[gij(j), gj] //если элементы на границах не в том порядке,
  66.           then begin
  67.             y := a[gij(j), gj]; //то меняем их местами
  68.             a[gij(j), gj] := a[gij(i), gj];
  69.             a[gi, gj] := y
  70.           end;
  71.         inc(i); //увеличиваем границы, по-любому за границами уже отсортировано
  72.         dec(j)
  73.       end;
  74.   until i >= j; //если границы встретились или поменялись местами, то сортировка текущего интекрвала закончена
  75.   if l < j then hoar(l, j); //если j больше нижней границы, рекурсивный вызов сортировки интервала от нижней границы до j
  76.   if i < r then hoar(i, r); //если i меньше нижней границы, рекурсивный вызов сортировки интервала от i до нижней границы
  77. end;
  78.  
  79. begin
  80.   randomize; //инициализация ГПСЧ
  81.   repeat //ввод размера массива с проверкой
  82.     write('n in [1..', m, '];  n = ');
  83.     readln(n)
  84.   until n in [1..m];
  85.   gen(n); //генерация массива
  86.   prn('Исходный массив:', n); //печать исходного массива
  87.   tn := n * (n + 1) div 2; //вычисление треугольного числа для последней строки массива
  88.   hoar(0, n * n - 1); //сортировка массива
  89.   prn('Отсортированный массив:', n); //вывод отсортированного массива
  90.   readln
  91. end.

Объяснение кода листинга программы

  1. Объявляются глобальная константа m со значением 10, и глобальные переменные n, tn, gi, gj типа целое число, и a - массив целых чисел размером m на m.
  2. Происходит определение процедуры gen, которая инициализирует значения массива a случайными числами.
  3. Определяется процедура prn для печати значений элементов массива.
  4. Функция gij получает индексы массива по числу k в хитрой змейке.
  5. Реализуется рекурсивная функция hoar для быстрой сортировки, с использованием хитрой змейки для доступа к элементам массива.
  6. В основном блоке программы инициализируется генератор псевдослучайных чисел, происходит ввод размера массива, инициализация массива, печать исходного массива, вычисление треугольного числа и сортировка массива при помощи функции hoar, вывод отсортированного массива. Note: Последующий код приведен в языке Pascal.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.067 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы