Вторая простая реализация
Вторая простая реализация
Однако при наличии большого количества элементов или при добавлении и удалении из очереди большого количества элементов она оказывается не столь эффективной, как хотелось бы. Уверен, что читатели сразу подумали об одном возможном способе повышения эффективности: поддержании структуры TList в порядке приоритетов. Иначе говоря, о поддержании ее в отсортированном виде в ходе всех добавлений. По существу, это усовершенствование означает перенос реальной задачи поддержания очереди из операции удаления элемента в операцию вставки элемента. При добавлении элемента необходимо найти для него правильную позицию внутри структуры TList после всех элементов с более низким приоритетом и перед всеми элементами с более высоким приоритетом. В случае выполнения этой дополнительной задачи на этапе добавления все элементы структуры TList будут размещены в порядке своих приоритетов и, следовательно, при удалении элемента потребуется всего лишь удалить последний элемент структуры. Фактически, при этом удаление превращается в операцию типа O(1) (нам точно известно, где расположен элемент с наивысшим приоритетом - он находится в конце очереди, поэтому удаление не зависит от количества элементов).
Вычисление времени, которое требуется для вставки в этот отсортированный список TList, несколько сложнее. Этот процесс проще всего представить сортировкой простыми вставками (которая была описана в главе 5). Мы увеличиваем размер TList на один элемент, а затем, подобно четкам, по одному перемещаем элементы на свободное место, начиная с конца структуры TList. Процесс прекращается по достижении элемента, приоритет которого ниже приоритета элемента, который мы пытаемся вставить. В результате в структуре TList образуется "пробел", в который можно поместить новый элемент. В структуре TList, содержащей n элементов, в среднем придется переместить nil элементов. Следовательно, вставка является операцией типа O(n) (т.е. требуемое для ее выполнения время снова пропорционально количеству элементов в очереди), хотя это усовершенствование позволяет несколько уменьшить время выполнения операции по сравнению с предыдущей реализацией. Пример кода выполнения этих двух операций в описанной структуре данных приведен в листинге 9.2.
Листинг 9.2. Очередь по приоритету, в которой используется отсортированная структура данных TList
type
TtdSimplePriQueue2 = class private
FCompare : TtdCompareFunc;
FList : TList;
protected
function pqGetCount : integer;
public
constructor Create(aCompare : TtdCompareFunc);
destructor Destroy; override;
function Dequeue : pointer;
procedure Enqueue(aItem : pointer);
property Count : integer read pqGetCount;
end;
constructor TtdSimplePriQueue2.Create(aCompare : TtdCompareFunc);
begin
inherited Create;
FCompare := aCompare;
FList := TList.Create;
end;
destructor TtdSimplePriQueue2.Destroy;
begin
FList.Free;
inherited Destroy;
end;
function TtdSimplePriQueue2.Dequeue : pointer;
begin
Result := FList.Last;
FList.Count := FList.Count - 1;
end;
procedure TtdSimplePriQueue2.Enqueue(aItem : pointer);
var
Inx : integer;
begin
{увеличить количество элементов в списке}
FList.Count := FList.Count + 1;
{определить место помещения нового элемента}
Inx := FList.Count -2;
while (Inx>= 0) and (FCompare(FList.List^ [Inx], aItem) > 0) do
begin
FList.List^[Inx+ 1] := FList.List^[Inx];
dec(Inx);
end;
{поместить элемент в эту позицию}
FList.List^[Inx+1] := aItem
end;
function TtdSimplePriQueue2.pqGetCount : integer;
begin
Result := FList.Count;
end;
Исходный код класса TtdSimplePriQueue2 можно найти на Web-сайте издательства, в разделе материалов. После выгрузки материалов отыщите среди них файл TDPriQue.pas.
В ходе разработки и создания этой усовершенствованной очереди по приоритету мы перешли от быстрой вставки/медленного удаления к медленной вставке/быстрому удалению. Нельзя ли воспользоваться более эффективным алгоритмом?
Еще одна возможность предполагает полный отказ от использования структуры TList и переход к другой структуре данных: дереву двоичного поиска, описанному в главе 8, или списку с пропусками, описанному в главе 6. При использовании обеих этих структур данных и вставка и удаление являются операциями типа O(log(n)). Иначе говоря, время, требуемое как для вставки, так и для удаления элемента, пропорционально логарифму числа элементов в структуре. Однако применение обеих этих структур данных сопряжено с некоторыми сложностями. В отношении списка с пропусками это связано с его вероятностной структурой, а в отношении дерева двоичного поиска - потому, что в ходе вставки и удаления необходимо заботиться о балансировке результирующего дерева. Существует ли какая-то более простая структура данных?
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Шаг первый: простая страница
Шаг первый: простая страница Вначале бралась обычная страница, для которой использовалось только gzip-сжатие HTML-файла. Это самое простое, что может быть сделано для ускорения загрузки страницы. Данная оптимизация бралась за основу, с которой сравнивалось все остальное. Для
Простая железнодорожная система
Простая железнодорожная система Вы легко построите железнодорожную систему, состоящую из одного пути с остановками и двумя простыми конечными точками. Обеспечьте энергией начало железной дороги, выкопав яму 2?1 и поместив в нее энергорельсы. Последний блок рельсов
Более простая версия функции str_cli
Более простая версия функции str_cli Неблокируемая версия функции str_cli, которую мы только что показали, нетривиальна: около 135 строк кода по сравнению с 40 строками версии, использующей функцию select с блокируемым вводом-выводом (см. листинг 6.2), и 20 строками начальной версии,
Пример: простая программа с уведомлением
Пример: простая программа с уведомлением Прежде чем углубляться в тонкости сигналов реального времени и потоков Posix, мы напишем простейшую программу, включающую отправку сигнала SI6USR1 при помещении сообщения в пустую очередь. Эта программа приведена в листинге 5.8, и мы
Глава 4 Простая
Глава 4 Простая В этой главе рассматриваются модификаторы и составные объекты. Действие модификаторов направлено на изменение формы объекта, взаимодействие двух объектов приводит к созданию третьего – составного. Моделирование с использованием модификаторов и
9.2. Простая ассемблерная вставка
9.2. Простая ассемблерная вставка Вот как с помощью функции asm() осуществляется сдвиг числа на 8 битов вправо:asm("shrl $8, %0" : "=r" (answer) : "r" (operand) : "cc");Выражение в скобках состоит из секций, разделенных двоеточиями. В первой секции указана ассемблерная инструкция и ее операнды.
Простая функция хеширования для строк
Простая функция хеширования для строк Похоже, что приведенные в предыдущем разделе рассуждения наталкивают на мысль о необходимости использования весовых коэффициентов, соответствующих позиции каждого символа в строке во избежание конфликтов при использовании
Первая простая реализация
Первая простая реализация При разработке очереди по приоритету первый атрибут (возможность хранения произвольного количества элементов) наталкивает на мысль об использовании какой-либо расширяемой структуры данных типа связного списка или расширяемого массива,
Простая реализация подсказок с помощью MFC
Простая реализация подсказок с помощью MFC Microsoft упростила добавление подсказок к кнопкам на панелях инструментов. Если вы используете AppWizard, этот процесс происходит автоматически. При генерации вашего приложения с помощью AppWizard щелкните флажок "Docking toolbar". После генерации
Пример 22-1. Простая функция
Пример 22-1. Простая функция #!/bin/bashfunky (){ echo "Это обычная функция."} # Функция должна быть объявлена раньше, чем ее можно будет использовать. # Вызов функции.funkyexit 0Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности
Простая архитектура PKI
Простая архитектура PKI Архитектура PKI может быть очень простой, если у пользователей - простые требования. В этом разделе рассматриваются два типа простой архитектуры: одиночный УЦ и списки доверия УЦ. Простая архитектура достаточна для связывания пользователей одного и