RSS    

   Реферат: VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования

    Loop

End Function

=======306

Программа Rand демонстрирует открытую адресацию с псевдослучайной проверкой. Она аналогична программам Linear и Quad, но использует псевдослучайную, а не линейную или квадратичную проверку.

В табл. 11.4 приведена примерная средняя длина тестовой последовательности, полученной в программах Quad или Rand для хеш‑таблицы со 100 ячейками и элементами, значения которых находятся в диапазоне от 1 до 999. Обычно псевдослучайная проверка дает наилучшие результаты, хотя разница между псевдослучайной и квадратичной проверками не так велика, как между линейной и квадратичной.

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

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

@Рис. 11.4. Длина поиска при использовании квадратичной и псевдослучайной проверки

=======307

Удаление элементов

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

Предположим, что элемент A находится в тестовой последовательности элемента B. Если удалить из таблицы элемент A, найти элемент B будет невозможно. Во время поиска элемента B встретится пустая ячейка, которая осталась после удаления элемента A, поэтому будет сделан неправильный вывод о том, что элемент B отсутствует в таблице.

Вместо удаления элемента из хеш‑таблицы можно просто пометить его как удаленный. Можно использовать эту ячейку позднее, если она встретится во время выполнения вставки нового элемента в таблицу. Если помеченный элемент встречается во время поиска другого элемента, он просто игнорируется и тестовая последовательность продолжится.

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

Рехеширование

Чтобы освободить удаленные элементы из хеш‑таблицы, можно выполнить ее рехеширование (rehashing) на месте. Чтобы этот алгоритм мог работать, нужно иметь какой‑то способ для определения, было ли выполнено рехеширование элемента. Простейший способ сделать это — определить элементы в виде структур данных, содержащих поле Rehashed.

Type ItemType

    Value As Long

    Rehashed As Boolean

End Type

Вначале присвоим полю Rehashed значение false. Затем выполним проход по таблице в поиске ячеек, которые не помечены как удаленные, и для которых еще не было выполнено рехеширование.

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

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

======308

Изменение размера хеш‑таблиц

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

Чтобы увеличить хеш‑таблицу, вначале размер массива, в котором она находится, увеличивается при помощи оператора Dim Preserve. Затем выполняется рехеширование таблицы, при этом элементы могут занимать ячейки в созданной свободной области в конце таблицы. После завершения рехеширования таблица будет готова к использованию.

Чтобы уменьшить размер таблицы, вначале определим, сколько элементов должно содержаться в массиве таблицы после уменьшения. Затем выполняем рехеширование таблицы, причем элементы помещаются только в уменьшенную часть таблицы. После завершения рехеширования всех элементов, размер массива уменьшается при помощи оператора ReDim Preserve.

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

Public Sub Rehash()

Dim i As Integer

Dim pos As Integer

Dim probes As Integer

Dim Value As Long

Dim new_value As Long

    ' Пометить все элементы как нерехешированные.

    For i = 0 To NumEntries - 1

        m_HashTable(i).Rehashed = False

    Next i

   

    ' Поиск нерехешированных элементов.

    For i = 0 To NumEntries - 1

        If Not m_HashTable(i).Rehashed Then

           Value = m_HashTable(i).Value

           m_HashTable(i).Value = UNUSED

           If Value <> DELETED And Value <> UNUSED Then

               ' Выполнить тестовую последовательность

               ' для этого элемента, пока не найдется свободная,

               ' удаленная или нерехешированная ячейка.

               probes = 0

               Do

                   pos = (Value + probes) Mod NumEntries

                   new_value = m_HashTable(pos).Value

                  

                   ' Если ячейка свободна или помечена как

                   ' удаленная, поместить элемент в нее.

                   If new_value = UNUSED Or _

                   new_value = DELETED _

                   Then

                       m_HashTable(pos).Value = Value

                       m_HashTable(pos).Rehashed = True

                       Exit Do

                   End If

                  

                   ' Если ячейка не помечена как рехешированная,

                   ' поменять их местами и продолжить.

                   If Not m_HashTable(pos).Rehashed Then

                       m_HashTable(pos).Value = Value

                       m_HashTable(pos).Rehashed = True

                       Value = new_value

                       probes = 0

                   Else

                       probes = probes + 1

                   End If

               Loop

           End If

        End If

    Next i

End Sub

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

Резюме

Различные типы хеш‑таблиц, описанные в этой главе, имеют свои преимущества и недостатки.

Для хеш‑таблиц, которые используют связные списки или блоки можно легко изменять размер таблицы и удалять из нее элементы. Использование блоков также позволяет легко работать с таблицами на диске, позволяя считать за одно обращение к диску сразу множество элементов данных. Тем не менее, оба эти метода являются более медленными, чем открытая адресация.

Линейная проверка проста и позволяет достаточно быстро вставлять и удалять элементы из таблицы. Применение упорядоченной линейной проверки позволяет быстрее, чем в случае неупорядоченной линейной проверки, установить, что элемент отсутствует в таблице. С другой стороны, вставку элементов в таблицу при этом выполнить сложнее.

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

В табл. 11.5 приведены преимущества и недостатки различных методов хеширования.

======310

@Таблица 11.5. Преимущества и недостатки различных методов хеширования

Выбор наилучшего метода хеширования для данного приложения зависит от данных задачи и способов их использования. При применении разных схем достигаются различные компромиссы между занимаемой памятью, скоростью и простотой изменений. Табл. 11.5 может помочь вам выбрать наилучший алгоритм для вашего приложения.

=======311

Глава 12. Сетевые алгоритмы

В 6 и 7 главах обсуждались алгоритмы работы с деревьями. Данная глава посвящена более общей теме сетей. Сети играют важную роль во многих приложениях. Их можно использовать для моделирования таких объектов, как сеть улиц, телефонная или электрическая сеть, водопровод, канализация, водосток, сеть авиаперевозок или железных дорог. Менее очевидна возможность использования сетей для решения таких задач, как разбиение на районы, составление расписания методом критического пути, планирование коллективной работы или распределения работы.

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82


Новости


Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

                   

Новости

© 2010.