- •Тема 1. Алгоритмы и программы 4
- •Тема 2. Характеристика языка Си 6
- •Тема 3. Основы языка Си 11
- •Тема 4.Работа с файлами 33
- •Тема 5.Распределение памяти 40
- •Тема 6. Методы организации данных в памяти эвм 43
- •Тема 7. Некоторые алгоритмы обработки данных 58
- •Тема 1. Алгоритмы и программы Цели и задачи изучения темы
- •1.1.Понятие алгоритма. Понятие программы. Способы записи алгоритмов.
- •1.2.Критерии качества программ
- •1.3.Низкоуровневые и высокоуровневые языки программирования
- •1.4.Принципы структурного программирования
- •Принципы структурного программирования.
- •2.2.Основные характеристики языка Си.
- •2.2.1.Достоинства языка Си
- •2.2.2.Компиляторы и интерпретаторы
- •2.2.3.Сильная типизация
- •2.3.Структура простой программы
- •Вопросы для повторения
- •3.1.2.Основные типы данных
- •3.1.3.Структуры данных
- •3.1.4.Оператор определения имени типа typedef
- •3.1.5.Массивы
- •3.1.6.Указатели
- •3.1.7.Указатели и массивы
- •3.1.8.Внешние и внутренние переменные
- •3.2.Стандартные функции ввода-вывода
- •3.3. Операции, операторы и выражения
- •3.3.1.Оператор присваивания
- •3.3.2.Арифметические операции
- •3.3.3.Операции увеличения и уменьшения
- •3.3.4.Операции сравнения
- •3.3.5.Логические операции
- •3.3.6.Побитовые логические операции
- •3.3.7.Операции сдвига
- •3.3.8.Операции "увеличить на", "домножить на" и т.П.
- •3.3.9.Операции с указателями. Указатели и массивы
- •3.3.10.Операция приведения типа
- •3.4.Управляющие конструкции
- •3.4.1.Фигурные скобки
- •3.4.2.Оператор выбора if и операция условия
- •3.4.3.Оператор множественного выбора switch
- •3.4.4.Оператор цикла while
- •3.4.5.Оператор цикла for
- •3.4.6.Оператор цикла do...While
- •3.5.Данные (более детальные сведения)
- •3.5.1.Структуры
- •3.5.2.Указатели и структуры
- •3.5.3.Структуры и оператор определения имени типа typedef
- •3.5.4.Строки
- •3.5.5.Матрицы и многомерные массивы
- •3.6.Пользовательские функции
- •3.6.1.Определение функций
- •3.6.2.Прототипы функций
- •3.6.3.Аргументы командной строки
- •Вопросы для повторения
- •4.2.Функция открытия файла fopen
- •4.3.Функции бинарного чтения и записи fread и fwrite
- •4.4.Функция закрытия файла fclose
- •4.5.Функции форматного чтения и записи fscanf и fprintf
- •4.6.Другие функции ввода-вывода
- •4.6.1.Функции посимвольного ввода-вывода
- •Int fgetc(file *f); - ввести один символ из файла f.
- •Int fputc(int c, file *f); - записать один символ в файл f.
- •4.6.2.Функции построкового ввода-вывода
- •Char *fgets(char *line,int size, file *f); - ввести строку из файла f.
- •Char *fputs(char *line, file *f); - записать строку в файл f.
- •4.6.3.Функции позиционирования в файле
- •Int fseek(file *f, long offset, int whence); - установить текущую позицию в файле f
- •Long ftell(file *f); - получить текущую позицию в файле f
- •Int feof(file *f); - проверить,достигнут ли конец файла f
- •Функция открытия файла fopen
- •Функции бинарного чтения и записи fread и fwrite
- •Функция закрытия файла fclose
- •5.2.Функции malloc и free
- •5.3.Выделение памяти под матрицы на этапе выполнения программы
- •Функции malloc и free.
- •6.2.Время выполнения программ
- •6.3.Списки
- •6.4.Реализация списков
- •6.5.Стеки
- •6.6.Реализация стеков
- •6.7.Очереди
- •6.8.Реализация очередей
- •6.9.Графы и деревья
- •6.10.Некоторые сд для хранения графов и деревьев
- •Матрица смежности графа, изображенного на рис.6.10
- •Матрица инцидентности графа, изображенного на рис.6.10
- •Матрица весов графа, изображенного на рис.6.11
- •Матрица смежности дерева, изображенного на рис.6.16
- •Вопросы для повторения
- •Реализация стеков.
- •Реализация очередей.
- •7.1.1.Поиск элемента в неупорядоченном массиве
- •7.1.2.Поиск элемента в упорядоченном массиве.
- •7.1.3.Фонетический поиск
- •7.2.Алгоритмы сортировки
- •7.2.1.Сортировка методом пузырька.
- •7.2.2.Сортировка вставками
- •7.2.3.Сортировка выбором
- •7.2.4.Пирамидальная сортировка
- •7.2.5.Быстрая сортировка
- •7.2.6.Сортировка слиянием
- •Этапы слияния файлов f1 и f2
- •7.3.Поиск на графах
- •7.3.1.Поиск в глубину
- •7.3.2.Поиск в ширину
- •7.4.Топологическая сортировка графа
- •7.5.Сетевое планирование
- •Информация о проекте
- •7.5.1.Алгоритм расчета наиболее ранних сроков наступления событий
- •7.5.2.Алгоритм расчета наиболее поздних сроков наступления событий
- •7.5.3.Алгоритм расчета резервов времени
- •Расчет резервов времени
- •Вопросы для повторения
7.2.2.Сортировка вставками
Еще один метод сортировки это метод вставками. Свое название метод получил из-за того, что на j-ой итерации происходит вставка j-го элемента массива X в нужную позицию среди элементов X[1],X[2],...,X[j-1], которые уже отсортированы. После выполнения этой вставки первые j элементов массива будут отсортированы. Подобным образом игроки упорядочивают свои карты, беря по одной. Работа алгоритма сортировки вставками проиллюстрирована на рис.7.5, алгоритм представлен блок-схемой на рис.7.6.
Время выполнения алгоритма сортировки вставками в худшем случае равно O(n2).
7.2.3.Сортировка выбором
Идея сортировки выбором состоит в том, что на j-ой итерации элементы массива разбиты на не отсортированную часть (элементы X[1],...,X[j]) и отсортированную часть (элементы X[j+1],...,X[n]). Среди первых j элементов массива X, составляющих не отсортированную часть массива, ищется наибольший элемент, пусть это i-ый элемент. После этого j-ый и i-ый элементы массива меняются местами. В результате отсортированная часть массива увеличивается на один элемент (элементы X[j],...,X[n]), а не отсортированная - уменьшается на один элемент (элементы X[1],...,X[j-1]). Выполнив n-1 таких итераций, получим массив, отсортированный в порядке возрастания.
Работа алгоритма сортировки выбором проиллюстрирована на рис.7.7, блок-схема алгоритма - на рис. 7.8.
Время выполнения алгоритма сортировки выбором в худшем случае равно O(n2).
7.2.4.Пирамидальная сортировка
Идея пирамидальной сортировки похожа на идею сортировки выбором. На текущей итерации среди элементов, составляющих не отсортированную часть массива, ищется наибольший элемент, который помещается в отсортированную часть. При этом число элементов в отсортированной части увеличивается на единицу, а в не отсортированной - уменьшается на единицу.
Принципиальное отличие пирамидальной сортировки от сортировки выбором заключается в организации поиска наибольшего элемента среди элементов составляющих не отсортированную часть массива.
В пирамидальной сортировке массив рассматривается как бинарное дерево (см. рис.7.9). Из каждой вершины дерева может выходить не более двух дуг. В дереве есть единственная вершина (корень дерева), в которую нет входящих дуг. Во все вершины отличные от корня входит ровно одна дуга. В дереве есть вершины из которых нет выходящих дуг (листья дерева). Каждый элемент массива соответствует вершине дерева. Пусть нумерация элементов массива и вершин дерева осуществляется натуральными числами, тогда данное соответствие устанавливается по следующим правилам:
каждый элемент массива с номером i соответствует вершине с номером i.;
первый элемент массива соответствует корню дерева;
из вершины с номером i выходят дуги в вершины с номерами i2 и i2+1 (такие вершины называются потомками вершины i). Если i2 или i2+1 больше числа вершин, то соответствующей дуги нет.
На первом шаге алгоритма пирамидальной сортировки бинарное дерево преобразуется в пирамиду. В пирамиде выполняется следующее условие: значение i-го элемента массива, соответствующего i-ой вершине дерева, из которой есть выходящие дуги в вершины k и (или) m, больше чем значения k-го и (или) m-го элемента массива.
После построения пирамиды максимальный элемент массива соответствует корню и находится на первом месте. После этого выполняется разрушение пирамиды - меняются местами первый и последний элементы массива.
После рассмотренных действий массив X, состоящий из n элементов, разбился на две части: не отсортированную и отсортированную. Не отсортированная часть массива состоит из элементов X[1],X[2],...,X[n-1]. Отсортированная часть массива состоит из единственного элемента X[n].
Далее процесс построения и разрушения пирамиды применяется к не отсортированной части массива. В результате не отсортированная часть массива будет состоять из элементов X[1],X[2],...,X[n-2], а отсортированная - из элементов X[n-1],X[n].
Выполнив n итераций построения и разрушения пирамиды, получим массив, отсортированный в порядке возрастания.
Алгоритм пирамидальной сортировки представлен блок-схемами на рис.7.10.
Пирамидальная сортировка эффективнее, чем сортировка выбором. Это связано с тем, что построение пирамиды после ее разрушения осуществляется за время O(log2m), где m-число элементов в не отсортированной части массива, в то время как поиск наибольшего элемента в сортировке выбором осуществляется медленнее, за время O(m).
Рассмотрим процесс построения пирамиды после ее разрушения более подробно. На рис.7.11 данный процесс проиллюстрирован для не отсортированной части массива, состоящей из 14 следующих элементов: 8, 11, 14, 7, 9, 13, 12, 2, 3, 4, 5, 6, 1, 10. Процесс построения пирамиды состоит из трех шагов. На каждом шаге для текущей вершины выбирается потомок с большим значением, и это значение сравнивается со значением текущей вершины. Если значение текущей вершины меньше чем значение выбранного потомка, то производится обмен данными значениями и выбранный потомок принимается в качестве текущей вершины.
На первом шаге в качестве текущей вершины выступает первая вершина. Потомками первой вершины являются вторая и третья вершины (см. рис.**). Значение третьей вершины равно 14, что больше 11 - значения второй вершины, поэтому выбирается третья вершина. Далее сравнивается значение текущей вершины (8) и третьей вершины (14). Значение текущей вершины меньше значения третьей вершины, поэтому происходит обмен данными значениями и третья вершина принимается в качестве текущей вершины.
Аналогично выполняется второй и третий шаги построения пирамиды после ее разрушения (см. рис.**). После выполнения данных шагов не отсортированная часть массива преобразована в пирамиду и состоит из следующих 14 элементов: 14, 11, 13, 7, 9, 8, 12, 2, 3, 4, 5, 6, 1, 10.
Отметим, что число шагов необходимых для построения пирамиды не может быть больше чем длина пути от корня до листьев дерева. А такая длина равна значению log2m округленному до наименьшего целого числа. Таким образом, построение пирамиды после ее разрушения осуществляется за время O(log2m).
Время выполнения алгоритма пирамидальной сортировки в худшем случае равно O(nlog2n). Таким образом, данная сортировка эффективнее всех ранее рассмотренных сортировок. Напомним, что все ранее рассмотренные сортировки имели порядок функции временной сложности O(n2).