Будет несколько (близко) связанных вопросов вместо одного. Для нашего удобства я пронумерую их соответствующим образом.
На основе этой статьи в Википедии, этот вопрос и лекции, думаю, я уже понял идею узлов-сторожей и их использования в связанных списках. Однако некоторые вещи мне до сих пор не ясны даже после прочтения этих материалов.
Мне дали базовую реализацию двусвязного списка (в нем хранятся только значения int), и задача состоит в том, чтобы изменить реализацию, чтобы она использовала дозорный узел, подобный этому:
Иллюстративное изображение (пока не разрешено вставлять изображения, извините)
Вопрос 1
Я предполагаю, что переменная head
списка будет указывать на первый реальный узел (тот, что после дозорного узла), а переменная tail
будет просто указывать на последний узел. Я прав или head
должен указывать на дозорный узел? Я прошу здесь о передовой практике или наиболее стандартном подходе.
вопрос 2
Я понимаю, что при поиске значения в списке мне больше не нужно проверять значение nullptr, так как я использую дозорный узел. Поскольку список в основном сформировал круг благодаря дозорному узлу, я должен завершить его после итерации по всему списку и достижения его. Могу ли я сделать это, поместив значение, которое я ищу, в дозорный узел и использовать его в качестве своего рода дозорного значения, а затем проверить, возвращается ли результат из дозорного узла, когда цикл заканчивается? Некоторые источники утверждают, что дозорные узлы вообще не должны хранить никаких значений. Является ли мой подход правильным/достаточно эффективным?
Вопрос 3
При простом повторении, а не при поиске определенного значения (например, подсчет узлов, вывод всего списка в консоль), нужно ли мне проверять дозорный узел так же, как и для nullptr (для завершения цикла итерации) или есть ли другой или более умный способ сделать это?