VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования
Категория реферата: Рефераты по информатике, программированию
Теги реферата: презентация дипломной работы, отчет по производственной практике
Добавил(а) на сайт: Памфил.
Предыдущая страница реферата | 20 21 22 23 24 25 26 27 28 29 30 | Следующая страница реферата
StackSize = LastItem + want_free
ReDim Preserve Stack(1 To StackSize)
End Sub
Этот вид реализации стеков достаточно эффективен в Visual Basic. Стек не расходует понапрасну память, и не слишком часто изменяет свой размер, особенно если сразу известно, насколько большим он должен быть.
=======51
Множественные стеки
В одном массиве можно создать два стека, поместив один в начале массива, а
другой — в конце. Для двух стеков используются отдельные счетчики длины
стека Top, и стеки растут навстречу друг другу, как показано на рис. 3.1.
Этот метод позволяет двум стекам расти, занимая одну и ту же область
памяти, до тех пор, пока они не столкнутся, когда массив заполнится.
К сожалению, менять размер этих стеков непросто. При увеличении массива
необходимо сдвигать все элементы в верхнем стеке, чтобы выделять память под
новые элементы в середине. При уменьшении массива, необходимо вначале
сдвинуть элементы верхнего стека, перед тем, как менять размер массива.
Этот метод также сложно масштабировать для оперирования более чем двумя
стеками.
Связные списки предоставляют более гибкий метод построения множественных
стеков. Для проталкивания элемента в стек, он помещается в начало связного
списка. Для выталкивания элемента из стека, удаляется первый элемент из
связного списка. Так как элементы добавляются и удаляются только в начале
списка, для реализации стеков такого типа не требуется применение
сигнальных меток или двусвязных списков.
Основной недостаток применения стеков на основе связных списков состоит в
том, что они требуют дополнительной памяти для хранения указателей
NextCell. Для стека на основе массива, содержащего N элементов, требуется
всего 2*N байт памяти (по 2 байта на целое число). Тот же стек, реализованный на основе связного списка, потребует дополнительно 4*N байт
памяти для указателей NextCell, увеличивая размер необходимой памяти втрое.
Программа Stack использует несколько стеков, реализованных в виде связных
списков. Используя программу, можно вставлять и выталкивать элементы из
каждого из этих списков. Программа Stack2 аналогична этой программе, но она
использует класс LinkedListStack для работы со стеками.
Очереди
Упорядоченный список, в котором элементы добавляются к одному концу списка, а удаляются с другой стороны, называется очередью (queue). Группа людей, ожидающих обслуживания в магазине, образует очередь. Вновь прибывшие подходят сзади. Когда покупатель доходит до начала очереди, кассир его обслуживает. Из-за их природы, очереди иногда называют списками типа первый вошел — первый вышел (First-In-First-Out list).
@Рис. 3.1. Два стека в одном массиве
=======52
Можно реализовать очереди в Visual Basic, используя методы типа
использованных для организации простых стеков. Создадим массив, и при
помощи счетчиков будем определять положение начала и конца очереди.
Значение переменной QueueFront дает индекс элемента в начале очереди.
Переменная QueueBack определяет, куда должен быть добавлен очередной
элемент очереди. По мере того как новые элементы добавляются в очередь и
покидают ее, размер массива, содержащего очередь, изменяется так, что он
растет на одном конце и уменьшается на другом.
Global Queue() As String ' Массив очереди.
Global QueuePront As Integer ' Начало очереди.
Global QueueBack As Integer ' Конец очереди.
Sub EnterQueue(value As String)
ReDim Preserve Queue(QueueFront To QueueBack)
Queue(QueueBack) = value
QueueBack = QueueBack + 1
End Sub
Sub LeaveQueue(value As String) value = Queue(QueueFront)
QueueFront = QueueFront + 1
ReDim Preserve Queue (QueueFront To QueueBack - 1)
End Sub
К сожалению, Visual Basic не позволяет использовать ключевое слово Preserve
в операторе ReDim, если изменяется нижняя граница массива. Даже если бы
Visual Basic позволял выполнение такой операции, очередь при этом
«двигалась» бы по памяти. При каждом добавлении или удалении элемента из
очереди, границы массива увеличивались бы. После пропускания достаточно
большого количества элементов через очередь, ее границы могли бы в конечном
итоге стать слишком велики.
Поэтому, когда требуется увеличить размер массива, вначале необходимо
переместить данные в начало массива. При этом может образоваться
достаточное количество свободных ячеек в конце массива, так что увеличение
размера массива может уже не понадобиться. В противном случае, можно
воспользоваться оператором ReDim для увеличения или уменьшения размера
массива.
Как и в случае со списками, можно повысить производительность, добавляя
сразу несколько элементов при увеличении размера массива. Также можно
сэкономить время, уменьшая размер массива, только когда он содержит слишком
много неиспользуемых ячеек.
В случае простого списка или стека, элементы добавляются и удаляются на
одном его конце. Если размер списка остается почти постоянным, его не
придется изменять слишком часто. С другой стороны, так как элементы
добавляются на одном конце очереди, а удаляются с другого конца, может
потребоваться время от времени переупорядочивать очередь, даже если ее
размер остается неизменным.
=====53
Const WANT_FREE_PERCENT = .1 ' 10% свободного пространства.
Const MIN_FREE = 10 ' Минимум свободных ячеек.
Global Queue() As String ' Массив очереди.
Global QueueMax As Integer ' Наибольший индекс массива.
Global QueueFront As Integer ' Начало очереди.
Global QueueBack As Integer ' Конец очереди.
Global ResizeWhen As Integer ' Когда увеличить размер массива.
' При инициализации программа должна установить QueueMax = -1
' показывая, что под массив еще не выделена память.
Sub EnterQueue(value As String)
If QueueBack > QueueMax Then ResizeQueue
Queue(QueueBack) = value
QueueBack = QueueBack + 1
End Sub
Sub LeaveQueue(value As String) value = Queue(QueueFront)
QueueFront = QueueFront + 1
If QueueFront > ResizeWhen Then ResizeOueue
End Sub
Sub ResizeQueue()
Dim want_free As Integer
Dim i As Integer
' Переместить записи в начало массива.
For i = QueueFront To QueueBack - 1
Queue(i - QueueFront) = Queue(i)
Next i
QueueBack = QueueBack - QueuePront
QueueFront = 0
' Изменить размер массива. want_free = WANT_FREE_PERCENT * (QueueBack - QueueFront)
If want_free < MIN_FREE Then want_free = MIN_FREE
Max = QueueBack + want_free - 1
ReDim Preserve Queue(0 To Max)
' Если QueueFront > ResizeWhen, изменить размер массива.
ResizeWhen = want_free
End Sub
При работе с программой, заметьте, что когда вы добавляете и удаляете
элементы, требуется изменение размера очереди, даже если размер очереди
почти не меняется. Фактически, даже при неоднократном добавлении и удалении
одного элемента размер очереди будет изменяться.
Имейте в виду, что при каждом изменении размера очереди, вначале все
используемые элементы перемещаются в начало массива. При этом на изменение
размера очередей на основе массива уходит больше времени, чем на изменение
размера описанных выше связных списков и стеков.
=======54
Программа ArrayQ2 аналогична программе ArrayQ, но она использует для управления очередью класс ArrayQueue.
Циклические очереди
Очереди, описанные в предыдущем разделе, требуется переупорядочивать время
от времени, даже если размер очереди почти не меняется. Даже при
неоднократном добавлении и удалении одного элемента будет необходимо
переупорядочивать очередь.
Если заранее известно, насколько большой может быть очередь, этого можно
избежать, создав циклическую очередь (circular queue). Идея заключается в
том, чтобы рассматривать массив очереди как будто он заворачивается, образуя круг. При этом последний элемент массива как бы идет перед первым.
На рис. 3.2 изображена циклическая очередь.
Программа может хранить в переменной QueueFront индекс элемента, который
дольше всего находится в очереди. Переменная QueueBack может содержать
конец очереди, в который добавляется новый элемент.
В отличие от предыдущей реализации, при обновлении значений переменных
QueueFront и QueueBack, необходимо использовать оператор Mod для того, чтобы индексы оставались в границах массива. Например, следующий код
добавляет элемент к очереди:
Queue(QueueBack) = value
QueueBack = (QueueBack + 1) Mod QueueSize
На рис. 3.3 показан процесс добавления нового элемента к циклической
очереди, которая может содержать четыре записи. Элемент C добавляется в
конец очереди. Затем конец очереди сдвигается, указывая на следующую запись
в массиве.
Таким же образом, когда программа удаляет элемент из очереди, необходимо
обновлять указатель на начало очереди при помощи следующего кода:
Рекомендуем скачать другие рефераты по теме: доклад по химии, конспект зима.
Предыдущая страница реферата | 20 21 22 23 24 25 26 27 28 29 30 | Следующая страница реферата