Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Технология программирования / ИТ / Лекции_Технология_прогр.doc
Скачиваний:
115
Добавлен:
17.05.2015
Размер:
848.38 Кб
Скачать

Алгоритм сортировки включением

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

Идея метода заключается в том, чтобы найти для элемента нужную позицию в массиве, поместить его туда, а оставшийся «хвост» массива сдвинуть вниз на одну позицию.

Рассмотрим этот метод на примере такой задачи: пусть в переменной new_stud хранится фамилия студента, которую нужно добавить в упорядоченный по алфавиту массив stud, не нарушая алфавитного порядка. Количество студентов в списке n.

Фрагмент программы может выглядеть примерно так:

i:=1; {начинаем просмотр с первого элемента списка}

while new_stud > stud[i] do i:=i+1;

{просматриваем список студентов, пропуская стоящих по алфавиту раньше вновь введенного, в позиции i должен стоять новый студент}

for j:=n downto i do

stud[j+1] := stud[j];{сдвигаем «хвост»}

stud[i] := new_stud;{помещаем нового студента в нужную позицию}

Отметим, что массив должен быть рассчитан на добавления, т. е. его размер должен позволять добавлять новые элементы.

Этот алгоритм дает линейную зависимость времени работы от длины массива.

Понятие вычислительной сложности алгоритма

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

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

§12. Обработка исключительных ситуаций

При работе любой не слишком примитивной программы может возникнуть ситуация, при которой дальнейшая работа становится невозможной. Например, преобразование строки в число не удается выполнить, поскольку строка содержит не цифры, а буквы, или не удается выполнить запись файла на диск, так как недостаточно свободного места, и т. п. Можно решить эту проблему введением многочисленных проверок, предотвращающих некорректные действия в случае возникновения нештатной ситуации. Но это сильно запутывает программу, затемняя четкую структуру основного алгоритма.

В языке Object Pascal предложен красивый выход из положения: вынести всю обработку исключительных ситуаций (ИС) из основной части, выделив в составе блока кода:

  • собственно реализацию алгоритма,

  • обработчик ИС,

  • заключительную часть, выполняющую необходимые действия по корректному завершению вне зависимости от того, возникали ИС или нет.

Для этого в языке существуют конструкции tryfinally и tryexcept.

Синтаксис блока try…finally таков:

try

<оператор>

<оператор>

finally

<оператор>

end;

Следующие за try операторы выполняются в обычном порядке. Если за это время не произошло никаких ИС, далее выполняются те операторы, которые стоят после finally. В случае, если между try и finally произошла ИС, управление немедленно передается на оператор(ы) после finally. Например, следующий фрагмент кода

a:=StrToInt(Edit1.Text); может привести к аварийному завершению программы, если в окно ввода Edit1 введено «1,2». Можно исправить ситуацию таким способом:

try

a:=StrToInt(Edit1.Text);

finally

Edit2.Text:=’OK’;

end;

Если преобразование происходит нормально, ИС не возникает. Если же ИС возникает, никаких сбоев в работе программы не наблюдается. В любом случае в окне Edit2 появляется надпись OK. Этот пример собственно обработки ИС не содержит, здесь важен только факт ее возникновения. Для реакции на конкретный тип ситуации применяется блок tryexcept. Синтаксис его следующий:

try

<оператор>

<оператор>

except

on Exception1 do <оператор>

on Exception2 do <оператор>

else {может отсутствовать}

<оператор> {обработчик ИС по умолчанию}

end;

Здесь, как и в предыдущем случае, выполнение блока начинается с секции try. В случае отсутствия исключительных ситуаций только она и выполняется. Секция except получает управление в случае возникновения ИС. Обработчик ИС состоит из набора директив ondo, задающих реакцию приложения на определенную ситуацию. Каждая директива связывает ситуацию (on), заданную своим именем, с группой операторов (do). При возникновении ИС директивы просматриваются последовательно, в порядке их появления. Если возникла ситуация, не определенная ни одной из директив, вызывается обработчик ИС по умолчанию. После обработки происходит выход из блока, и управление обратно в секцию try не передается.

Вернемся к предыдущему примеру. Для корректной работы программы следовало бы в случае возникновения ИС выдать сообщение об этом, а не бессмысленное в данном случае OK. Сделать это можно следующим образом:

try

a:=StrToInt(Edit1.Text);

except

on EConvertError do Edit1.Text:='Ошибка ввода';

end;

Программные коды всех исключительных ситуаций включены в объектный тип Exception и содержатся в модуле SysUtils.

Приведем некоторые важные ИС:

Ситуация

Возникает при условии

EConvertError

Невозможность преобразования данных

EOutOfResources

Нехватка системных ресурсов

ИС целочисленной математики

EDivByZero

Попытка деления на ноль

ERangeError

Число или выражение выходит за допустимый диапазон

EIntOverflow

Целочисленное переполнение

ИС математики с плавающей точкой

EInvalidOp

Неверная операция

EZeroDivide

Попытка деления на ноль

EOverflow

Переполнение с плавающей точкой

Отметим, что обработка ИС, описанная в блоке try, будет выполняться должным образом только при запуске exe-файла приложения прямо из Windows. При запуске из среды Delphi обработка ИС будет перехвачена, и вы увидите сообщение Delphi. В этом сообщении, кстати, можно узнать имя возникшей ИС.

Соседние файлы в папке ИТ