Автор оригинала: Pankaj Kumar.
Двойно круговой связанный список – это структура данных, которая используется для хранения записей в списке. Это принципиально так же, как связанные списки, но с несколькими дополнительными основными моментами. В этом руководстве мы посмотрим на то, что такое вдвойне круговой связанный список, как сделать один в Python, и что является его выходом.
Предпосылки
Мы должны сначала обсудить несколько структур данных, прежде чем переходить на вдвойне круговые связанные списки.
1. Связанные списки
Связанный список – это список, в котором элементы связаны с другими элементами определенным образом. Различные типы связанных списков имеют разные способы связывания элементов.
Самый простой связанный список – это «по отдельно связанным списком» или просто «связанный список». В этом каждый элемент ссылается на следующий элемент в списке. (Но не в обратном порядке). Итак, для доступа к NTH Pithone, нам нужно будет получить доступ к пункту (N-1) ITE. И доступ к пункту NTH позволяет нам получить доступ к пункту (N + 1) TH списка.
У нас есть прямой доступ к первому элементу списка, используя, что мы можем получить доступ к 2-м одному, а затем 3-й и т. Д. До последнего элемента, который не имеет доступа к любому другому элементу в списке.
Каждый элемент в связанном списке называется узлом. Каждый узел имеет часть, которая хранит свои данные, а другая часть для хранения ссылки/ссылки на следующий узел.
2. Вдвойне связанные списки
Вдвойне связанные списки аналогичны связанным спискам, но в этом случае каждый узел имеет две ссылки, один на следующий узел и один на предыдущий узел.
Таким образом, чтобы получить доступ к NT-узлу, нам нужно будет сначала получить доступ к узлу (N-1) или узлу (N + 1). И после того, как мы получили доступ к NT-узлу, используя его, мы можем получить доступ к узлу (N-1) или узлу (N + 1). То есть обход может случиться в любом направлении.
Каждый узел изготовлен из трех частей, один для данных и двух других для предыдущих и следующих ссылок. Это выглядит что-то подобное:
3. Круговые связанные списки
Круглые связанные списки также аналогичны связанным спискам, единственное различие, являющееся тем, что последний узел ссылается на первый узел вместо того, чтобы не иметь ссылки. Таким образом, он образует круговую связь между узлами, и если мы продолжим доступ к следующим узлам, он никогда не заканчивается и вернет к началу после первого узла.
Это выглядит что-то подобное:
Вдвойне круговые связанные списки
Теперь, когда мы знаем, как выглядят вдвойне связанные списки и круговые связанные списки, как выглядят трудно понять, что будет вдвойне круговой связанный список.
Здесь каждый узел содержит три части, один для данных, а два других для ссылок. Каждый узел ссылается на следующие и предыдущие узлы списка. Для первого узла нет предыдущего узла, поэтому он идет по кругу и ссылкам на последний узел списка. Точно так же для последнего узла нет следующего узла, поэтому он идет по кругу и ссылкам на первый узел списка.
Чтобы получить доступ к любому узлу, нам нужно получить доступ к узлу после него или узла перед ним, и после доступа к любому узлу узлы после и до того, как он может быть напрямую доступен. Но мы также можем получить доступ к последнему узлу прямо с первого узла и наоборот.
Визуализировать, вдвойне круговой связанный список выглядит что-то подобное:
В приведенном выше примере вы можете видеть, что в списке четыре узла есть четыре узла, и каждый узел подключен к узлу после него и узла перед ним. Последний узел указывает на второй последний узел и первый узел, и первый узел указывает на последний узел и второй узел.
Глава указывает на начало списка, и теперь мы можем либо пересекать вперед и достичь конца, либо мы можем пройти назад и достичь запуска списка.
Реализация вдвойне круговых связанных списков в Python
Мы должны создать два класса, один для узлов, а другой, который будет использовать узлы для создания связанного списка.
Класс: узел
class Node: def __init__(self, data = None): self.data = data self.previous = self self.next = self
Первоначально при создании узла он укажет на себя в обоих направлениях сформировать вдвойне круговой связанный список только с одним элементом.
Класс: вдвойне круговой связанный список
class DCLL: def __init__(self): self.head = None self.count = 0 def __repr__(self): string = "" if(self.head == None): string += "Doubly Circular Linked List Empty" return string string += f"Doubly Circular Linked List:\n{self.head.data}" temp = self.head.next while(temp != self.head): string += f" -> {temp.data}" temp = temp.next return string def append(self, data): self.insert(data, self.count) return def insert(self, data, index): if (index > self.count) | (index < 0): raise ValueError(f"Index out of range: {index}, size: {self.count}") if self.head == None: self.head = Node(data) self.count = 1 return temp = self.head if(index == 0): temp = temp.previous else: for _ in range(index - 1): temp = temp.next temp.next.previous = Node(data) temp.next.previous.next, temp.next.previous.previous = temp.next, temp temp.next = temp.next.previous if(index == 0): self.head = self.head.previous self.count += 1 return def remove(self, index): if (index >= self.count) | (index < 0): raise ValueError(f"Index out of range: {index}, size: {self.count}") if self.count == 1: self.head = None self.count = 0 return target = self.head for _ in range(index): target = target.next if target is self.head: self.head = self.head.next target.previous.next, target.next.previous = target.next, target.previous self.count -= 1 def index(self, data): temp = self.head for i in range(self.count): if(temp.data == data): return i temp = temp.next return None def get(self, index): if (index >= self.count) | (index < 0): raise ValueError(f"Index out of range: {index}, size: {self.count}") temp = self.head for _ in range(index): temp = temp.next return temp.data def size(self): return self.count def display(self): print(self)
Вышеуказанный класс содержит много методов, давайте обсудим их один за другим.
То __в этом__ метод
Мы объявляем двух членов, голова
и Считать
Инициализирован Нет
и 0
Соответственно, потому что в списке нет узлов в списке.
То __repr__ метод
__repr__
Способ вернет строку, которая напечатает содержимое списка на экране.
То присоединиться к а также вставлять метод
Мы можем либо добавить или вставлять узлы в списке. Добавить
Метод создан только для удобства, поскольку он называет Вставить
Способ и отправляет соответствующие значения.
В Вставить
Способ, мы сначала проверим, если индекс
находится в диапазоне или нет, а если нет, мы поднимаем ValueError
Отказ Затем, если список пуст, то мы просто назначаем новый узел для голова
и сделать Считать
равный 1. Теперь мы достигаем узла непосредственно перед индекс
где новый узел должен быть вставлен.
На данный момент мы делаем предыдущий
узла по указанному индексу, равным новым узлам. Затем мы делаем новый узел Следующий
и предыдущий
равный узлу по указанному индексу и узеру до указанного индекса соответственно. И теперь мы делаем Следующий
из узла до указанного индекса, равный новому узлу. Наконец, если указанный индекс был 0
тогда мы делаем голова
указать на узел незадолго до того, как он указывал.
Просто увеличивайте Считать
и Вставить
метод сделан.
То Удалить метод
В этом методе мы впервые проверим, если индекс
не имеет диапазона и бросать ValueError
если это. Тогда, если только один узел, мы просто сделаем голова
как Нет
и сделать Считать
как 0
и вернуться.
Если нет, мы достигаем необходимого узла, который будет удален, и если целевой узел является голова
мы делаем голова
Укажите на узел после этого, чтобы мы не теряем список.
Наконец, мы делаем Следующий
из узла до указанного указателя точки на узел после указанного индекса, и мы делаем предыдущий
из узла после указанного указателя указывают на узел до указанного индекса. Это сделает узел по указанному индексу, недостойным из списка (в основном пропущенном), и мы уменьшаем количество, чтобы закончить метод.
То индекс , получать , размер , а также отображать метод
индекс
Метод ищет линейно через список и возвращает индекс, если элемент найден, Нет
иначе.
получить
Метод возвращает элемент по указанному индексу и повышает ValueError
Если индекс вне диапазона.
Размер
Метод возвращает количество элементов в списке.
Дисплей
Метод печатает список.
Выход
Заключение
В этом руководстве мы подробно изучили вдвое круговое соединенное списком и реализовали его в Python. Надеюсь, вам понравилось узнать об этом и увидимся в следующем руководстве.