- •1. Типы данных
- •Для записи в конец файла необходимо, чтобы была установлена ситуация Eof (логическая функция Eof возвращала true). Чтение файла возможно при отсутствии ситуации Eof.
- •2. Линейные списки
- •2.1. Стеки
- •2.2. Очереди и их применение
- •Продвижение очереди производится операторами
- •Пусть имеется n клиентов. Обозначим через m[I] момент прихода, а через t[I] время обслуживания I-го клиента. Рассмотрим алгоритм решения задачи.
- •2.3. Двусвязные списки и мультисписки
- •3. Деревья
- •3.1. Организация в памяти и рекурсивный обход
- •3. 2. Обход деревьев с помощью стека
- •3.3. Пример программы с обходами деревьев
- •4. Графы
- •4.1. Представление графа. Транзитивное замыкание
- •.2. Пример программы с использованием матрицы смежности
- •4.3. Обход графа в глубину. Поиск путей
- •4.4. Обход графа в ширину
- •4.5. Алгоритмы поиска кратчайших путей Дейкстры и Флойда
- •5. Поиск данных
- •5.1. Последовательный, индексно-последовательный, бинарный поиск
- •4.2. Бинарные деревья поиска
- •5.3. Балансировка деревьев поиска
- •5.5. Хеширование
- •6. Сортировка данных
- •6.1. Методы внутренней сортировки
- •6.2. Методы внешней сортировки
- •Заключение
- •Литература
- •Содержание
Заключение
Опыт показывает, что необходимое для применения на практике понимание основных структур данных и алгоритмов их обработки достигается только после написания собственных программ. Имеет смысл привести наиболее распространенные ошибки на стадиях проектирования и разработки программ.
Постановка задачи понимается неправильно. Порой это выясняется только при сдаче учебной программы. Часто студентами предъявляются претензии о некорректной или недостаточно полной формулировке задачи. Следует иметь в виду, что реальные задания на создание программного обеспечения как правило неполны, неточны и противоречивы. Достаточная ясность возможна только при тесном контакте с заказчиком. При обучении в роли такого заказчика выступает преподаватель.
Алгоритмическая проработка задачи проводится поверхностно. В результате при тестировании выявляются принципиальные ошибки.
Отсутствует проектирование структуры программы. В итоге с трудом просматривается логическая схема программы, неоправданно употребляются операторы безусловной передачи управления (goto), встречаются дублирующие друг друга фрагменты текста, затруднены тестирование и модификация программы.
Текст программы сложен для восприятия и проверки. Для повышения “удобочитаемости” программы рекомендуется [7,8]:
применять осмысленные имена переменных;
резко ограничивать использование одних и тех же идентификаторов для различных целей;
вставлять подробные комментарии, поясняющие назначение и функционирование программных фрагментов;
применять отступы в тексте программы, выделяющие группы операторов и показывающие вложенность программных единиц.
Существенные трудности вызывает этап тестирования. В литературе до сих пор встречается следующее определение: ”Тестирование – это процесс, подтверждающий правильность программы и демонстрирующий, что ошибок в программе нет”. Это определение обладает серьезными недостатками. Во-первых, невозможно доказать отсутствие ошибок в любой достаточно сложной программе. Во-вторых, определение психологически настраивает программиста на подбор таких тестов, на которых программа выполняется правильно.
Более точное определение: “Тестирование – это процесс выполнения программы с целью нахождения ошибок” [7, 8]. Следуя данному определению, цель тестирования – заставить программу сбиться, “сломать” программу.
Обычно тестирование и отладка требуют большей трудоемкости, чем разработка программы. Рекомендуется придерживаться следующих правил тестирования [7, 8].
Выбор теста должен преследовать цель обнаружения ошибки, а не демонстрации правильности работы программы.
Тесты должны проверять как соответствие получаемых результатов условиям задачи, так и внутреннюю логику программы. Минимальный критерий при тестировании логики программного модуля: в каждой точке ветвления следует по крайней мере один раз пройти все пути (это не сводится к исследованию всех возможных путей программы).
Необходимая часть всякого теста – описание ожидаемых результатов. Желательно прогнозировать результаты до выполнения теста.
Тесты должны охватывать как правильные, так и неправильные данные.
Результаты выполнения каждого теста должны тщательно анализироваться и объясняться. Необходимо фиксировать все тесты, на которых выявились ошибки. Распространенной порочной практикой является изменение теста при появлении ошибок.
Необходимо учитывать известный парадокс тестирования: чем больше ошибок найдено в некоторой части программы, тем больше вероятность обнаружения в этой части новых ошибок.
