
- •Основы алгоритмизации и программирования, язык Си
- •Введение
- •Блок-схема алгоритма Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Описание переменных
- •Локальные переменные
- •Операции и выражения
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора Директива #include
- •Директива #define
- •Понятие пустого и составного операторов
- •Условные операторы
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Операторы перехода (break, continue, return, goto)
- •Примеры программ
- •Массивы Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Параметры по умолчанию
- •Передача массива в функцию
- •Inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Доступ к элементам структуры
- •Инициализация структур
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Примеры программ
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Потоки и файлы
- •Файлы Основные сведения о файловой системе
- •Организация посимвольного ввода и вывода
- •Определение конца файла feof()
- •Организация ввода и вывода строк
- •Удаление файлов
- •Дозапись потока
- •Позиционирование в файле
- •Текстовые и двоичные файлы
- •Функции fread() и fwrite()
- •Примеры программ
- •Хеширование
- •Схемы хеширования
- •Метод открытой адресации с линейным опробыванием
- •Метод цепочек
- •Машинное представление графов
- •Примеры программ
- •Литература
Сортировка
Сортировка применяется во многих программах оперирующих информацией. Цель сортировки – упорядочить информацию и облегчить поиск требуемых данных. Существует много методов сортировки данных. Причём для разных типов данных иногда целесообразно применять разные методы сортировки.
Практически каждый алгоритм сортировки можно разбить на три части:
- сравнение двух элементов, определяющее упорядоченность этой пары;
- перестановку, меняющую местами неупорядоченную пару элементов;
- сортирующий алгоритм, определяющий выбор элементов для сравнения и отслеживающий общую упорядоченность массива данных.
Сортировка данных в оперативной памяти называется внутренней, а сортировка данных в файлах называется внешней. Ниже будут рассматриваться методы сортировки данных в оперативной памяти.
Пузырьковая сортировка.
Название метода отражает его суть. ”Легкие” элементы массива ”всплывают” вверх (в начало), а ”тяжелые” опускаются вниз(в конец). Пузырьковая сортировка проходит по массиву снизу вверх. Каждый элемент массива сравнивается с элементом, который находится непосредственно над ним. И если при их сравнении оказывается, что они удовлетворяют условию их перестановки, то она выполняется. Процесс сравнений и перестановок продолжается до тех пор, пока ”легкий” элемент не “всплывет” вверх. В конце каждого прохода по массиву, верхняя граница сдвигается на один элемент вниз(вправо). Сортировка продолжается анализируя все меньшие массивы. В примере выполняется сортировка элементов массива размерностью k.
void sort(int *ms, int k)
{ int i,j,m;
for(i=0;i<k-1;++i) // выбор верхней границы массива
for(j=k-1;j>i;--j) // просмотр массива ”снизу” ”вверх”
{if(ms[j-1]>ms[j]) // условие замены выполнено
{ m=ms[j-1]; // замена j-1 и j элементов
ms[j-1]=ms[j];
ms[j]=m;
}
}
}
Внутренний цикл for выполняет проход по подмассиву в направлении обратном внешнему циклу. Если изменить направление этих циклов, то не наименьший будет “всплывать”, а наибольший “тонуть”.
Шейкер сортировка
В этом методе учитывается тот факт, что от последней перестановки до конца массива будут находиться уже упорядоченные данные. Тогда просмотр имеет смысл делать не до конца массива, а до последней перестановки на предыдущем просмотре. Если же просмотр делать попеременно в двух направлениях и фиксировать нижнюю и верхнюю границы неупорядоченной части, то получим шейкер-сортировку. Ниже приведен пример программы, использующей шейкер-сортировку элементов массива размерностью k.
void shaker(int *ms, int k)
{ register int i,a,b,c,d;
c=1;
b=k-1; //номер элемента на котором остановка
d=k-1; //номер стартового элемента для сортировки справа налево
do
{ for(i=d;i>=c;--i)
{ if (ms[i-1]>ms[i])
{ a=ms[i-1];
ms[i-1]=ms[i];
ms[i]=a;
b=i; // крайний слева упорядоченный элемент
}
}
c=b+1; //номер стартового элемента для сортировки слева направо
for(i=c;i<=d;++i)
{ if (ms[i-1]>ms[i])
{ a=ms[i-1];
ms[i-1]=ms[i];
ms[i]=a;
b=i; // крайний слева упорядоченный элемент
}
}
d=b-1;
} while(c<=d);
}