Сторожевой узел - Sentinel node
Эта статья не цитировать любой источники.Январь 2016) (Узнайте, как и когда удалить этот шаблон сообщения) ( |
Эта статья может требовать уборка встретиться с Википедией стандарты качества. Конкретная проблема: Резюме может быть корочеЯнварь 2016) (Узнайте, как и когда удалить этот шаблон сообщения) ( |
В компьютерном программировании дозорный узел специально обозначенный узел используется с связанные списки и деревья как ограничитель пути обхода. Этот тип узла не содержит и не ссылается на какие-либо данные, управляемые структурой данных.
Преимущества
Стражи используются как альтернатива использованию НОЛЬ
в качестве ограничителя пути, чтобы получить одно или несколько из следующих преимуществ:
- Незначительно повышенная скорость работы
- Увеличенная структура данных надежность (возможно)
Недостатки
- Незначительно увеличенная алгоритмическая сложность и размер кода.
- Если к структуре данных осуществляется доступ одновременно (что означает, что все узлы, к которым осуществляется доступ, должны быть защищены как минимум на «Только для чтения» ), для реализации на основе дозорного устройства дозорный узел должен быть защищен от «чтения-записи» с помощью мьютекс. Этот дополнительный мьютекс во многих сценариях использования может вызвать серьезное снижение производительности.[1]. Один из способов избежать этого - защитить структуру списка в целом от «чтения-записи», тогда как в версии с
НОЛЬ
достаточно защитить структуру данных в целом «только для чтения» (если не последует операция обновления). - Концепция дозорного устройства бесполезна для записи структуры данных на диск.
Примеры
Поиск
Ниже представлены две версии подпрограммы (реализованной в Язык программирования C ) для поиска заданного ключа поиска в односвязный список. Первый использует контрольное значение НОЛЬ
, а второй (указатель на) сторожевой узел Часовой
, как индикатор конца списка. Объявления структуры данных односвязного списка и результаты обеих подпрограмм одинаковы.
структура sll_node { // один узел односвязного списка int ключ; структура sll_node *следующий; // индикатор конца списка или -> следующий узел} sll, *первый;
Первая версия с использованием NULL в качестве индикатора конца списка
1 // глобальная инициализация 2 первый = НОЛЬ; // перед первой вставкой (не показано) 3 4 структура sll_node *Поиск(структура sll_node *первый, int search_key) { 5 структура sll_node *узел; 6 за (узел = первый; 7 узел != НОЛЬ; 8 узел = узел->следующий) 9 {10 если (узел->ключ == search_key)11 возвращаться узел; // найденный12 }13 // не найден14 возвращаться НОЛЬ;15 }
В за
-loop содержит два теста (желтые линии) на итерацию:
узел! = NULL;
если (узел-> ключ == search_key)
.
Вторая версия с использованием дозорного узла
Глобально доступный указатель часовой
в специально подготовленную структуру данных Часовой
используется как индикатор конца списка.
1 // глобальная переменная 2 sll_node Часовой, *часовой = &Часовой; 3 // глобальная инициализация 4 часовой->следующий = часовой; 5 первый = часовой; // перед первой вставкой (не показано) 6 // Обратите внимание, что указатель всегда должен находиться в конце списка. 7 8 структура sll_node *SearchWithSentinelnode(структура sll_node *первый, int search_key) { 9 структура sll_node *узел;10 часовой->ключ = search_key;11 за (узел = первый; 12 узел->ключ != search_key;13 узел = узел->следующий)14 {15 }16 если (узел != часовой)17 возвращаться узел; // найденный18 // не найден19 возвращаться НОЛЬ;20 }
В за
-loop содержит только один тест (желтая линия) на итерацию:
узел-> ключ! = ключ_поиска;
.
Реализация связанного списка
Реализации связанного списка, особенно кругового двусвязного списка, можно значительно упростить, используя контрольный узел для разграничения начала и конца списка.
- Список начинается с единственного узла, сигнального узла, у которого есть следующий и предыдущий указатели, которые указывают на себя. Это условие определяет, пуст ли список.
- В непустом списке следующий указатель сторожевого узла дает начало списка, а предыдущий указатель дает конец списка.
Ниже представлена реализация кругового двусвязного списка на Python:
учебный класс Узел: def __в этом__(себя, данные, следующий=Никто, предыдущий=Никто) -> Никто: себя.данные = данные себя.следующий = следующий себя.предыдущий = предыдущий def __repr__(себя) -> ул: возвращаться 'Узел (данные ={})'.формат(себя.данные)учебный класс LinkedList: def __в этом__(себя) -> Никто: себя._sentinel = Узел(данные=Никто) себя._sentinel.следующий = себя._sentinel себя._sentinel.предыдущий = себя._sentinel def pop_left(себя): возвращаться себя.remove_by_ref(себя._sentinel.следующий) def поп(себя): возвращаться себя.remove_by_ref(себя._sentinel.предыдущий) def append_nodeleft(себя, узел) -> Никто: себя.add_node(себя._sentinel, узел) def append_node(себя, узел -> Никто): себя.add_node(себя._sentinel.предыдущий, узел) def append_left(себя, данные) -> Никто: узел = Узел(данные=данные) себя.append_nodeleft(узел) def добавить(себя, данные) -> Никто: узел = Узел(данные=данные) себя.append_node(узел) def remove_by_ref(себя, узел): если узел является себя._sentinel: поднимать Исключение(«Никогда не убрать часового».) узел.предыдущий.следующий = узел.следующий узел.следующий.предыдущий = узел.предыдущий узел.предыдущий = Никто узел.следующий = Никто возвращаться узел def add_node(себя, курнод, новый узел) -> Никто: новый узел.следующий = курнод.следующий новый узел.предыдущий = курнод курнод.следующий.предыдущий = новый узел курнод.следующий = новый узел def поиск(себя, ценить): себя._sentinel.данные = ценить узел = себя._sentinel.следующий пока узел.данные != ценить: узел = узел.следующий себя._sentinel.данные = Никто если узел является себя._sentinel: возвращаться Никто возвращаться узел def __iter__(себя): узел = себя._sentinel.следующий пока узел является нет себя._sentinel: урожай узел.данные узел = узел.следующий def ревитер(себя): узел = себя._sentinel.предыдущий пока узел является нет себя._sentinel: урожай узел.данные узел = узел.предыдущий
Обратите внимание, как add_node ()
метод принимает узел, который будет перемещен новым узлом в параметре курнод
. Для добавления слева это заголовок непустого списка, а для добавления справа - хвост. Но из-за того, как настроена связь для обратной ссылки на дозорного, код работает и для пустых списков, где курнод
будет дозорным узлом.
Смотрите также
- Сторожевое значение
- Магическое число (программирование)
- Волшебная струна
- Шаблон пустого объекта
- Ошибки форматирования и хранения времени
- Слон в Каире
- Канареечное значение
- Полупредикатная проблема
Рекомендации
- ^ Игнатченко, Сергей (1998), "Реализации STL и безопасность потоков", Отчет C ++
Этот компьютерное программирование -связанная статья является заглушка. Вы можете помочь Википедии расширяя это. |