Благодарю за отличную лекцию. Твой материал по linkedList дал абсолютное его понимание. Все пересмотренное и прочитанное ранее такой ясности не дало. Успехов тебе. Ты большой молодец.
Большое тебе спасибо, очень доступно и понятно объяснил данную тематику, плюсом хочу поблагодарить за демонстрацию такого типа создания односвязаного списка, у тебя получилось гораздо понятней чем у других.
Если апенд реализовывать, как в видео, получается перебор всего списка для добавления в конец. В таком случае сложность алгоритма линейная О(n), зависит от количества элементов списка. Для pushback и pushfront должна быть константная О(1). А вот инсерты не в пограничные позиции можно сделать только с перебором. Можно добавить помимо head еще и tail. Для первого элемента условие if head is none и if tail is none : head = current, tail = current. Для последующих элементов (если head != none): tail.next = current (делаем связь последнего элемента с новым), tail = current (переставляем указатель хвост на новый (последний) элемент). Если список двухсвязанный, то еще добавляется связь current.previous = tail до перестановки указателя хвоста на новый элемент
@Роман Рахлин, спасибо за видео, для меня материал очень полезен, но в функции remove() ошибка - если в списке находится только 1 элемент и сделать удаление my_list.remove(0) - этот элемент в нем и останется. надо блок if, где проверка индекса на 0, вынести из цикла while и сделать проверку до цикла, иначе с одним эелементом цикл while никогда не выполнится, потому что next вернет None.
Очень понятное объяснение Linked List. Если не ошибаюсь то LinkedList можно было бы развернуть в цикле длиной LinkedList.length каждый раз переставлять второй элемент в начало списка и после этого удалять второй элемент, используя уже написанные функции push_front и remove Например так (у меня методы класса названы чуть по другому): def reverse_me_2(self): i = 0 while i < len(self) - 1: self.insert_first(self.value_at(i + 1)) self.remove_node_at(i + 2) i += 1
Чел, спасибо тебе, начало было немного странное, потому что когда видишь лицо автора поначалу не понимаешь какой контент будет, а тут прям доходчиво и очень понятно что и куда, короче очень годно! Респект!
Особенно хреново это, когда сидишь в наушниках. Прибавляешь звук, чтобы услышать автора видео, так как в начале слишком тихо, а потом просто после переключения экрана глохнешь от звука
Кто-нибудь объясните, почему использовав переменную в функции add_element, но не использовав ее в функции show, результат все равно оказался корректным? def add_element(self,value): if not self.head: self.head = Node(value) return cur = self.head while cur.follow is not None: cur = cur.follow cur.follow = Node(value) def show(self): collector = '' while self.head: collector += f'[{self.head.value}]-->' self.head = self.head.follow collector += 'None' print(collector) При этом, если в функции add_element все делать не через переменную cur, а напрямую использовать self.head и тд, то отображаться в результате будут только последние 2 элемента в связном списке?
1) Связный список одна из самых бесполезных структур данных. Даже дядька который его придумал (не помню его имени) написал, что за 25 лет ни разу его не использовал в работе, как и 99.9999% разработчиков. 2) геттеры и сеттеры в питоне это позорище, как минимум лучше просто обращать к полям, а как максимум использовать @property. Но если эти методы просто присваивают значение, то их использование это только лишние строки кода 3) == None?????ахахаха Серьёзно? Тут обязан быть оператор is или is not там, где != Зашел посмотреть чисто, что тут можно объяснять 50 минут, даже на лекции в универе этой бесполезной теме посвещают максимум 20, просто чтобы люди знали что такое есть.
Автор, ты немного недопонял, как работают связные списки. Смотри: у тебя операции добавления ноды в конец выполняются за линейное время, что довольно долго. Это происходит потому что ты используешь 1 указатель, который итерируется по всем нодам. Это немного неправильно. В связных списках должно быть 2 указателя (1 - начальный указатель, который может итерироваться до n-1 позиции. 2 указатель - всегда остаётся на последней ноде).
Конечно я новичок и понимаю, что пригодиться может всё. Но в итоге самые эффективные методы это когда мы по индексу добавляем или удаляем элемент в списке. Они хоть и самые большие, но в целом если прописать только 2 метода и работать с элементами в списке только по индексам это же будет удобнее и в плане кода выйдет меньше, чем запоминать и прописывать сразу все методы.
Ну скорее всего чтобы сделать массив, нужно итерировать до последнего элемента связного списка включительно и собирать все элементы в массив. Это очень похоже на метод вывода, где мы проходились и собирали все в строку
Благодарю за отличную лекцию. Твой материал по linkedList дал абсолютное его понимание. Все пересмотренное и прочитанное ранее такой ясности не дало. Успехов тебе. Ты большой молодец.
Большое тебе спасибо, очень доступно и понятно объяснил данную тематику, плюсом хочу поблагодарить за демонстрацию такого типа создания односвязаного списка, у тебя получилось гораздо понятней чем у других.
Знаешь дружище я пересмотрел столько туториалов по связанному списку, но понял только твой. ты большой молодец. Спасибо
Отличный гайд, спасибо, дополнил собственный код парой очень удобных идей твоих.
Лучшее объяснение на youtube!!!! спасибо! подписка
Рома опять делает топчик
Солидарен.
Если апенд реализовывать, как в видео, получается перебор всего списка для добавления в конец. В таком случае сложность алгоритма линейная О(n), зависит от количества элементов списка. Для pushback и pushfront должна быть константная О(1). А вот инсерты не в пограничные позиции можно сделать только с перебором.
Можно добавить помимо head еще и tail.
Для первого элемента условие if head is none и if tail is none : head = current, tail = current.
Для последующих элементов (если head != none): tail.next = current (делаем связь последнего элемента с новым), tail = current (переставляем указатель хвост на новый (последний) элемент). Если список двухсвязанный, то еще добавляется связь current.previous = tail до перестановки указателя хвоста на новый элемент
Очень хорошее и понятное объяснение!! красава
@Роман Рахлин, спасибо за видео, для меня материал очень полезен,
но в функции remove() ошибка - если в списке находится только 1 элемент и сделать удаление my_list.remove(0) - этот элемент в нем и останется.
надо блок if, где проверка индекса на 0, вынести из цикла while и сделать проверку до цикла, иначе с одним эелементом цикл while никогда не выполнится, потому что next вернет None.
Спасибо, друг! Очень полезно было :)
Очень понятное объяснение Linked List.
Если не ошибаюсь то LinkedList можно было бы развернуть в цикле длиной LinkedList.length каждый раз переставлять второй элемент в начало списка и после этого удалять второй элемент, используя уже написанные функции push_front и remove
Например так (у меня методы класса названы чуть по другому):
def reverse_me_2(self):
i = 0
while i < len(self) - 1:
self.insert_first(self.value_at(i + 1))
self.remove_node_at(i + 2)
i += 1
Чел, спасибо тебе, начало было немного странное, потому что когда видишь лицо автора поначалу не понимаешь какой контент будет, а тут прям доходчиво и очень понятно что и куда, короче очень годно! Респект!
Особенно хреново это, когда сидишь в наушниках. Прибавляешь звук, чтобы услышать автора видео, так как в начале слишком тихо, а потом просто после переключения экрана глохнешь от звука
супер объяснение, спасибо!
Спасибо большое, все очень понятно объясняешь 🤍
Супер, благодарю
зачем нужно было писать геттеры и сеттеры, если атрибуты публичные?
Спасибо за видос, бро!)
Спасибо, классное видео, надеюсь будет еще!)
Приветствую! Хорошее видео, однако хотелось бы посмотреть на то как отсортировать связный список.
большоооооооооооооооооооооое спасибо!продолжай в том же духе!
❤️🔥❤️🔥❤️🔥
ку, спасибо за видос. А это на пучарме можно сделать? Если да, подскажи как классы написать
Спасибо большое
Thank you
Кто-нибудь объясните, почему использовав переменную в функции add_element, но не использовав ее в функции show, результат все равно оказался корректным?
def add_element(self,value):
if not self.head:
self.head = Node(value)
return
cur = self.head
while cur.follow is not None:
cur = cur.follow
cur.follow = Node(value)
def show(self):
collector = ''
while self.head:
collector += f'[{self.head.value}]-->'
self.head = self.head.follow
collector += 'None'
print(collector)
При этом, если в функции add_element все делать не через переменную cur, а напрямую использовать self.head и тд, то отображаться в результате будут только последние 2 элемента в связном списке?
Почему сравнение с array? Разве list не чаще используется в Python?
👍
а разве нельзя просто добавлять дату нодов в новый лист и делать ретурн листа с [::-1]
я 200 попищек где мой приз
help me
1) Связный список одна из самых бесполезных структур данных. Даже дядька который его придумал (не помню его имени) написал, что за 25 лет ни разу его не использовал в работе, как и 99.9999% разработчиков.
2) геттеры и сеттеры в питоне это позорище, как минимум лучше просто обращать к полям, а как максимум использовать @property. Но если эти методы просто присваивают значение, то их использование это только лишние строки кода
3) == None?????ахахаха Серьёзно? Тут обязан быть оператор is или is not там, где !=
Зашел посмотреть чисто, что тут можно объяснять 50 минут, даже на лекции в универе этой бесполезной теме посвещают максимум 20, просто чтобы люди знали что такое есть.
Спасибо, нихера не понятно
Автор, ты немного недопонял, как работают связные списки. Смотри: у тебя операции добавления ноды в конец выполняются за линейное время, что довольно долго. Это происходит потому что ты используешь 1 указатель, который итерируется по всем нодам. Это немного неправильно. В связных списках должно быть 2 указателя (1 - начальный указатель, который может итерироваться до n-1 позиции. 2 указатель - всегда остаётся на последней ноде).
Конечно я новичок и понимаю, что пригодиться может всё. Но в итоге самые эффективные методы это когда мы по индексу добавляем или удаляем элемент в списке. Они хоть и самые большие, но в целом если прописать только 2 метода и работать с элементами в списке только по индексам это же будет удобнее и в плане кода выйдет меньше, чем запоминать и прописывать сразу все методы.
Прошу огромное прошение за чёрный экран начиная с 02:42 минуты! Вот картинка которая должна была там быть 👉 m.imgur.com/a/6B8StHR
для длины было было логичнее переопределить магический метод __len__
@@AntonyKondr тогда лучше на С)
Вообще не мог понять эту тему. Но после просмотра этого обьясненя прям прозрел. Спасибо автору!!!
Тупил с этим линкедлистом, не мог найти видоса, твой помог, стал лучше понимать как это работает, осталось с реверсом до конца вникнуть и все, спасибо
Роман, огромное тебе спасибо. Ты спас мою нервную систему . Наконец-то до меня дошло, как это работает.👍
Шикаррно! Лучшее объяснение
@user-jd3hb4vd2z
может запишешь еще нам видосик про double LL и другие структуры данных которые ты уже умеешь реализовывать?
Спасибо за видео. Не мог бы ты ещё подсказать, как из получившегося списка сделать массив?
Ну скорее всего чтобы сделать массив, нужно итерировать до последнего элемента связного списка включительно и собирать все элементы в массив. Это очень похоже на метод вывода, где мы проходились и собирали все в строку
👏
Лучший!
Самое классное объяснение связанных списков. Спасибо
Крутой материал, спасибо!
Спасибо за примеры. Помогло вникнуть глубже.
Молодец спасибо!
Спасибо! помогло
Спасибо 🤜🤛