Рубрики
Без рубрики

Изменить связанные списки, как босс – в Python

<< Неделя 7: связанные списки | Просмотр решения на GitHub | Неделя 9: Blockchain >> Некоторые из моих… Теги с Python, Computerscience, CodeNewie, начинающими.

<< Неделя 7: связанные списки |. Просмотр решения на GitHub |. Неделя 9: Blockchain >>

Некоторые из моих любимых ссылок. (Изображение: TV Tropes)

Добро пожаловать обратно в доске в Python. На прошлой неделе мы говорили о связанных списках: что они, как сделать один в Python. Вы, вероятно, подумали: «Отлично. Но какова фактическая точка для этого? Разве мы не можем просто использовать обычный список Python? ” Хороший вопрос.

Вы видите, до сих пор мы только что сделали связанный список, но мы ничего не сделали с ним. Забудьте о списках Python на мгновение и подумайте о массиве. На многих объектных ориентированных языках, таких как Java, массивы фиксированы длина. Это означает, что если вы хотите добавить или удалить пространство, вам нужно сделать новый и переместить все предыдущее содержимое в него. Это как если бы вы жили в доме с 3 спальнями, и вдруг вам нужна была 4-й спальня: вам придется собрать все свои вещи и переехать в новый дом с четырьмя спальнями.

Теперь списки Python не являются настоящими массивами, но реализованные динамические массивы, которые имеют разные характеристики из связанных списков и массивов (дополнительная информация здесь ). Но, по крайней мере, по сравнению со старыми массивами, связанные списки составляют манипулирование списками гораздо проще, потому что нам не нужно иметь совершенно новый список, чтобы добавить один узел. Мы просто делаем новый узел и измените указатели из других узлов.

Давайте посмотрим на образец задачу:

# Remove Dups: Write code to remove duplicates 
# from an unsorted linked list.

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

class Node:
  def __init__(self, data):
    self.next = None
    self.data = data

  def append(self, val):
    end = Node(val)
    n = self
    while (n.next):
      n = n.next
    n.next = end

Давайте начнем с определения метода удаления дубликатов. Это займет один параметр, первый узел в списке. Я назову это спереди Отказ

def remove_dups(front):
    pass

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

Обзор, по умолчанию Это объект в коллекциях Python, что позволяет устанавливать тип по умолчанию для значений в словаре. Мы можем установить это на бол Так что, если у ключа нет предыдущего значения, он автоматически настроит его на false. Итак, импортируют его и инициализируем наш словарь. Я назову это подсчитанный , так как он представляет, видели или нет каждую ценность раньше.

from collections import defaultdict
def remove_dups(front):
  counted = defaultdict(bool)

Теперь мы должны сделать наш итератор для прохождения списка. Вы можете вспомнить это с прошлой недели, мы делаем отдельный узел, чтобы указать на каждый узел в списке, «пересекающий» его, и это оставляет исходный список неповрежденный. Вот полезный GIF от GeeksForGeeks, где указатель пересекает связанный список и удаляет последний узел:

Итак, давайте сделаем наш указатель. Традиционно мы можем назвать это Temp Отказ

temp = front

Теперь давайте поговорим о прохождении. Мы могли бы проверить значение первого узла, затем переместиться на 2-е место и проверять его значение, и так далее, но у нас будет проблема. Что если узел мы смотрели, имели дублирующее значение? Мы можем изменить только его Следующий Указатель, а не указатель, который идет до этого. Итак, мы посмотрим на значение каждого Следующий узел, и если это происходит дубликат, мы настроим temp.next быть Нет Отказ

Например, скажем, это наш список:

[1] –> [1] –> [2]

Мы начинаем с того, что выкладываете значение первого узла, 1, в нашем Считается толковый словарь.

counted[temp.data] = True

Далее, пока все еще указывая на первый узел, мы смотрим на значение temp.next Отказ Поскольку это значение является дубликатом, мы хотим удалить узел. Итак, мы устанавливаем temp.next быть узлом после этого, temp.next.next Отказ

 counted[temp.data] = True
 while (temp.next):
    # check the value of next Node
    if (counted[temp.next.data]):
      # if found in dictionary, remove it
      temp.next = temp.next.next

Если значение temp.next не правда в подсчитанный Мы хотим настроить его на правду. Затем мы хотим перейти на следующий узел, установив Temp быть temp.next .

counted[temp.data] = True
 while (temp.next):
    # check the value of next Node
    if (counted[temp.next.data]):
      #if found in dictionary, remove it
      temp.next = temp.next.next
    else:
      counted[temp.next.data] = True
      temp = temp.next

Вот и все! Вот полный метод:

from collections import defaultdict
def remove_dups(front):
  counted = defaultdict(bool)
  temp = front
  counted[temp.data] = True
  while (temp.next):
    # check the value of next Node
    if (counted[temp.next.data]):
      #if found in dictionary, remove it
      temp.next = temp.next.next
    else:
      counted[temp.next.data] = True
      temp = temp.next

Тестирование нашего метода

Посмотрим, работает ли наш метод. Мы начнем, создавая связанный список и добавление некоторых номеров к нему.

ll = Node(1)
ll.append(2)
ll.append(3)
ll.append(3)
ll.append(1)
ll.append(4)

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

node = ll
print(node.data)
while node.next:
    node = node.next
    print(node.data)

Это должно печатать 1 , 2 , 3 , 3 , 1 , 4 Отказ Теперь, когда у нас есть наш список построен, давайте назовем метод на нем. Вы помните, что мы прошли перед линейным списком, что происходит LL Отказ

remove_dups(ll)

Если все работает гладко, и вы снова распечатаете список, дополнительно 1 и 3 следует удалить, чтобы дать 1 , 2 , 3 , 4 Отказ

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

Вот и это за на этой неделе. Дайте мне знать, если вам нравится этот контент, и благодаря всем вам оставляют комментарии. Было здорово видеть, как сообщество участвует, и то, как мы все узнаем больше (я включаю в себя)!

<< Неделя 7: связанные списки |. Просмотр решения на GitHub |. Неделя 9: Blockchain >>

Sheamus Heikkila ранее преподавательский помощник в Генеральной Ассамблее Сиэтл. Этот блог не связан с GA.

Оригинал: “https://dev.to/pythonwb/modify-linked-lists-like-a-boss-in-python-565j”