- •Введение
- •Блок-схема алгоритма
- •Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Основные понятия языка С(С++)
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Структура программы на языке С(С++)
- •Операции и выражения
- •sizeof
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Операторы языка С(С++)
- •Понятие пустого и составного операторов
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Примеры программ
- •Массивы
- •Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели
- •Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Передача массива в функцию
- •inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Вершина стека
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Стек
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Файлы
- •Примеры программ
- •Литература
каждого этапа отстоящие на gap элементы отсортированы.
Рассмотрим пример. Рассортировать массив чисел: 41,53,11,37,79,19,7,61. В строке после массива в круглых скобках указаны индексы
сравниваемых элементов и указан номер внешнего цикла.
41 |
53 11 37 79 19 |
7 |
61 |
– исходный массив. |
|
|
|
|
||||
41 |
19 11 37 79 53 |
7 |
61 |
– (0,4), (1,5) |
|
|
|
1-ый цикл |
||||
|
|
|
||||||||||
41 |
19 |
7 37 79 53 |
11 |
61 |
– (2,6), (3,7) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
7 |
19 41 37 11 53 |
79 |
61 |
– (0,2),(1,3),(2,4),(3,5),(4,6),(5,7) |
|
|
2-ой цикл |
|||||
|
||||||||||||
7 |
19 11 37 41 53 |
79 |
61 |
– (0,2),(1,3),(2,4),(3,5),(4,6),(5,7) |
|
|
|
|||||
|
|
|
||||||||||
|
||||||||||||
7 |
11 19 37 41 53 |
61 |
79 |
– сравнивались соседние.(3-ий цикл). |
||||||||
void sort(int *ms, int k) |
|
|
|
|
|
|
|
|
|
|||
{ int i, j, n; |
|
|
|
|
|
|
|
|
|
|
||
|
int |
gap; |
// шаг сортировки |
|
|
|
|
|||||
|
int |
flg; |
// флаг окончания этапа сортировки |
for(gap = k/2; gap > 0; gap /= 2) do
{flg = 0;
for(i = 0, j = gap; j < k; i++, j++)
if(*(ms+i) > *(ms+j)) // сравниваем отстоящие на gap элементы
{n = *(ms+j); *(ms+j) = *(ms+i); *(ms+i) = n;
flg = 1; |
// есть еще не рассортированные данные |
} |
|
} while (flg); |
// окончание этапа сортировки |
}
Метод Хора
Алгоритм быстрой сортировки построен на основе идеи разбиения массива на разделы. Общая процедура заключается в выборе пограничного значения, называемого компарандом, которое разбивает сортируемый массив на две части. Все элементы, значения которых больше пограничного значения, переносятся в один раздел, а все элементы с меньшими значениями - в другой. Затем это процесс повторяется для каждой из частей и так до тех пор, пока массив не будет отсортирован. Например, допустим, что необходимо отсортировать следующий массив: "fedacb". Если в качестве компарадера использовать "d", то после первого прохода алгоритм быстрой сортировки упорядочит массив следующим образом
Исходный массив |
Fedacb |
Проход 1 |
Bcadef |
Затем этот подход повторяется для каждого раздела, а именно "bca" И
"def".
Проход 2 |
Acb |
Def |
Проход 3 |
Abc |
Def |
Процесс рекурсивен по своей природе и наилучшие решения получаются при рекурсивном подходе. Пограничное значение можно выбирать двумя путями. Во-первых, его можно делать случайным образом, или путем осреднения небольшого набора значений, принадлежащих к разделу. Для того, чтобы сортировка была оптимальной, надо выбирать значение, расположенное точно в середине диапазона значений. Поскольку на практике это не всегда осуществимо, можно выбирать срединный элемент каждого из разделов.
Метод Хоора (Charles Antony Richard Hoare, 1962 г.), называемый также методом быстрой сортировки (Quicksort) основывается на следующем: находится такой элемент, который разбивает множество на два подмножества так, что в одном все элементы больше, а в другом - меньше делящего. Каждое из подмножеств также разделяется на два, по такому же признаку. Конечным итогом такого разделения станет рассортированное множество. Рассмотрим один из вариантов реализации сортировки Хоора.
В процедуре сортировки сначала выберем срединный элемент. Далее, в слева от срединного элемента выбираются элементы большие, а в правой – меньшие срединного. Найденные элементы меняются местами. это выполняется пока ленная и правая границы не равны. В результате будут получены два подмножества. Если эти подмножества существуют, то выполняем по отдельности их сортировку.
Например, необходимо рассортировать массив: 13,3,23,19,7,53,29,17. Переставляемые элементы будем подчёркивать, средний - выделим жирным шрифтом, а элемент попавший на своё место и не участвующий в последующих сравнениях - наклонным шрифтом. Индекс i будет задавать номер элемента слева от среднего, а j справа от среднего.
13 |
3 23 |
19 |
7 53 29 17 |
13 |
3 17 |
19 |
7 53 29 23 |
13 |
3 17 |
7 19 53 29 23 |
делим на два подмножества |
13 |
3 |
17 |
7 |
19 53 29 23 |
||||||||
Выделяем подмножество |
|
|
|
|
|
|
|
|
|
||||
3 |
13 |
17 |
7 |
19 23 29 53 |
|
|
|
|
|
|
|
||
|
|
|
|
13 |
17 |
|
7 |
|
|
|
|
||
Выделяем подмножество 13 |
7 |
|
|
17 |
|
|
|
|
|||||
Результат: |
|
3 |
|
7 |
|
13 |
17 |
|
19 23 29 53 |
||||
// |
l – левая r – правая границы сортируемого массива |
||||||||||||
void hoar(int |
*ms, int |
l, int r) // передаем левую/правую границы |
|||||||||||
{ |
int |
i, j, k; |
|
|
|
|
|
|
|
|
|
|
|