Компания ALT Linux
Опубликован: 07.03.2015 | Доступ: свободный | Студентов: 1836 / 300 | Длительность: 24:14:00
Лекция 5:

Массивы

5.4.6.2 Сортировка выбором

Алгоритм сортировки выбором приведён в виде блок-схемы на рис. 5.14. Идея алгоритма заключается в следующем. В массиве Y, состоящем из n элементов, ищем самый большой элемент (блоки 2–5) и меняем его местами с последним элементом (блок 7). Повторяем алгоритм поиска максимального элемента, но последний (n - 1)-й элемент не рассматриваем, так как он уже занял свою позицию.

Сортировка массива выбором наибольшего элемента

Рис. 5.14. Сортировка массива выбором наибольшего элемента

Найденный максимум ставим на (n - 2)-ю позицию. Описанную выше операцию поиска проводим n-1 раз, до полного упорядочивания элементов в массиве. Фрагмент программы выполняет сортировку массива по возрастанию методом выбора:

for ( j =1; j<n; b=y [ n-j ], y [ n-j ]=y [ nom ], y [ nom]=b, j++)
	for (max=y [ 0 ], nom=0, i =1; i<=n-j; i++)
		if ( y [ i ]>max) {max=y [ i ]; nom= i; }

Для упорядочивания массива по убыванию необходимо менять минимальный элемент с последним элементом.

5.4.6.3 Сортировка вставкой

Сортировка вставкой заключается в том, что сначала упорядочиваются два элемента массива. Затем делается вставка третьего элемента в соответствующее место по отношению к первым двум элементам. Четвёртый элемент помещают в список из уже упорядоченных трёх элементов. Этот процесс повторяется до тех пор, пока все элементы не будут упорядочены.

Прежде чем приступить к составлению блок–схемы, рассмотрим следующий пример. Пусть известно, что в массиве из десяти элементов первые шесть уже упорядочены (с нулевого по пятый), а шестой элемент нужно вставить между вторым и четвёртым. Сохраним шестой элемент во вспомогательной переменной, а на его место запишем пятый. Далее четвёртый переместим на место пятого, а третий на место четвёртого, тем самым выполнив сдвиг элементов массива на одну позицию вправо. Записав содержимое вспомогательной переменной в третью позицию, достигнем нужного результата.

Составим блок–схему алгоритма (рис. 5.15), учитывая, что возможно описанные выше действия придётся выполнить неоднократно.

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

Рис. 5.15. Сортировка массива вставкой

Организуем цикл для просмотра всех элементов массива, начиная с первого (блок 1). Сохраним значение текущего i–го элемента во вспомогательной переменной b, так как оно может быть потеряно при сдвиге элементов (блок 2), и присвоим переменной j значение индекса предыдущего (i - 1)–го элемента массива (блок 3). Далее движемся по массиву влево в поисках элемента, меньшего чем текущий, и, пока он не найден, сдвигаем элементы вправо на одну позицию. Для этого организуем цикл (блок 4), который прекратиться, как только будет найден элемент меньше текущего. Если такого элемента в массиве не найдётся и переменная j станет равной (-1), то это будет означать, что достигнута левая граница массива, и текущий элемент необходимо установить в первую позицию. Смещение элементов массива вправо на одну позицию выполняется в блоке 5, а изменение счётчика j в блоке 6. Блок 7 выполняет вставку текущего элемента в соответствующую позицию. Далее приведён фрагмент программы, реализующей сортировку массива методом вставки.

for ( i =1; i<n; y [ j +1]=b, i++)
	for ( b=y [ i ], j=i -1;( j >-1 && b<y [ j ] ); y [ j +1]=y [ j ], j --);

Рассмотрим несколько несложных задач, связанных с упорядочиванием.

Задача 5.11. Задан массив a[n], упорядоченный по убыванию, вставить в него некоторое число b, не нарушив упорядоченности массива.

Массив является упорядоченным по убыванию, если каждое последующий элемент массива не больше предыдущего, т. е. при выполнении следующей совокупности неравенств a_0 \ge a_1 \ge a_2 \ge ... \ge a_{n-3} \ge a_{n-2} \ge a_{n-1}.

Для вставки в подобный массив некоторого числа без нарушений упорядоченности, необходимо:

  1. Найти номер k первого числа в массиве, которое a_k ‎ b.
  2. Все элементы массива a, начиная от n-1 до k-го, сдвинуть на один вправо4Очень важно, что сдвиг осуществляем от n - 1-го до k-го, в противном случае элементы массива оказались бы испорченными..
  3. На освободившееся место с номером k записать число b.

Текст программы с комментариями приведён ниже.

#include <iostream>
2 using namespace std;
	int main ( int argc, char **argv )
4 {
	int i, k, n;
6 	float b;
	cout<<" n = "; cin>>n; //Ввод размера исходного массива.
8 	float a [ n + 1 ]; //Выделение памяти с учётом предстоящей вставки одного числа в массив.
	cout<<"Введите массив a \n "; //Ввод исходного упорядоченного по убыванию массива.
10 	for ( i =0; i<n; i++)
		cin>>a [ i ];
12 	cout<<"Введите число b = "; cin>>b; //Ввод вставляемого в массив числа b .
	//Если число b меньше всех элементов массива, записываем b в последний элемент массива.
14 	if ( a [ n-1]>=b ) a [ n ]=b;
	else //Иначе
16 	{
		for ( i =0; i<n; i++) //Ищем первое число, меньшее b .
18 		if ( a [ i ]<=b )
		{
20 			k= i; //Запоминаем его номер в переменной k .
			break;
22 		}
		for ( i=n-1; i>=k; i --) //Все элементы массива от n -1-го до k-го сдвигаем на один вправо.
24 			a [ i +1]=a [ i ];
		a [ k ]=b; //Вставляем число b в массив.
26 	}
	cout<<"Преобразованный массив a \n ";
28 	for ( i =0; i<=n; i++)
	cout<<a [ i ]<<" \t ";
30 	return 0;
}

Обратите внимание, при решении задачи с массивом, упорядоченным по возрастанию необходимо во фрагменте со строки 14 по строку 22 заменить все операции отношения на противоположные.

Задача 5.12. Проверить, является ли массив упорядоченным по возрастанию.

Для проверки упорядоченности по возрастанию a[n]5Массив является упорядоченным по возрастанию, если выполняются условия a_0 \le a_1 \lea_2 \le ... \le a_{n-3} \le a_{n-2} \le a_{n-1}. можно поступить следующим образом. Предположим, что массив упорядочен (pr=true). Если хотя бы для одной пары соседних элементов выполняется условие a_i > a_{i+1}, то массив не упорядочен по возрастанию (pr=false). Текст программы с комментариями приведён ниже. Читателю предлагается преобразовать программу таким образом, чтобы осуществлялась проверка, упорядочен ли массив по убыванию.

#include <iostream> namespace std;
int main ( int argc, char **argv )
{
	int i, n;
	bool pr;
	cout<<" n = "; cin>>n; //Ввод размера исходного массива.
	float *a=new float [ n ]; //Выделение памяти для массива.
	cout<<"Введите массив a \n "; //Ввод исходного массива.
	for ( i =0; i<n; i++)
		cin>>a [ i ];
	//Предполагаем, что массив упорядочен (pr=true), перебираем все пары соседних значений
	//(i — номер пары), при i равном n - 2 будем сравнивать последнюю пару a[n-2] и a[n-1].
	for ( pr=true, i =0; i<n-1; i++)
	//Если для очередной пары соседних элементов выяснилось, что предыдущий элемент больше
	//последующего, то массив неупорядочен по возрастанию (pr=false), остальные пары соседних
	//значений, можно не проверять (оператор break)
		if ( a [ i ]>a [ i +1 ]) { pr=false; break; }
	if ( pr ) cout<<"Массив упорядочен по возрастанию";
	else cout<<"Массив не упорядочен по возрастанию";
	return 0;
}
Сергей Радыгин
Сергей Радыгин

Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке?

Тип приложения - не Qt,

Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.

 

Юрий Герко
Юрий Герко

Кому удалось собрать пример из раздела 13.2 Компоновка (Layouts)? Если создавать проект по изложенному алгоритму, автоматически не создается  файл mainwindow.cpp. Если создавать этот файл вручную и добавлять в проект, сборка не получается - компилятор сообщает об отсутствии класса MainWindow. Как правильно выполнить пример?