Расширьте свои основы CS, изучив связанные списки

TL;DR

  • Используйте связанные списки для больших списков данных, где общее количество элементов в списке неизвестно/изменяется.
  • Связанные списки имеют динамический размер, эффективную вставку/удаление, отсутствие случайного доступа и ненужной траты памяти.
  • Массивы имеют фиксированный размер (не в Javascript), неэффективные вставки/удаления, произвольный доступ и потенциальную трату памяти

Мотивация для написания

Когда я подумывал о том, чтобы записаться на буткемп по веб-разработке, чтобы облегчить смену карьеры, одна вещь, которая всегда беспокоила меня, — это очевидный разрыв в основах информатики (CS) между выпускниками буткемпа и людьми со степенью CS. Естественно, буткемпы сосредоточены на развитии прикладных навыков, в то время как университетские программы CS делают акцент на изучении теоретических концепций. Хотя можно получить должность младшего разработчика, не имея сильных основ CS, я считаю, что устойчивая карьера — это разработка программного обеспечения, требующая прочной основы CS. Пытаясь изучить концепции CS, я решил изучить связанные списки.

Что такое связанный список?

Связанный список — это структура данных, в которой несколько значений хранятся линейным образом. Другими словами, связанные списки представляют собой последовательность узлов, где каждый узел указывает на следующий узел в списке. В этой статье мы сосредоточимся на односвязном списке (каждый узел имеет только один указатель на другой узел, который чаще всего вызывается следующим). Чтобы узнать больше о двусвязном списке (каждый узел имеет две ссылки, обычно называемые предыдущей и следующей), не стесняйтесь посетить это руководство. Если вы амбициозны, изучите круговые связанные списки.

Связный список имеет следующие свойства:

  • Последовательные узлы соединены указателями
  • Последний узел указывает на ноль
  • Поддерживается головной указатель, который указывает на первый узел списка.
  • Связанный список может увеличиваться и уменьшаться в размере во время выполнения программы.
  • Это может быть сделано так долго, как требуется
  • Выделяет память по мере роста списка

Связанные списки и массивы

Как разработчики Javascript, вы можете задаться вопросом, зачем нужны связанные списки, особенно когда существует другая линейная структура данных: массивы. На самом деле можно сделать карьеру разработчика Javascript, не внедряя связанные списки. Так чем же отличаются массивы и связанные списки? По сути, в связном списке элементы связаны через цепочку ссылок, тогда как в массивах элементы размещаются по индексам. Существуют варианты использования для обоих типов структур данных. Давайте рассмотрим за и против этих двух структур данных.

Преимущества использования связанных списков перед массивами

  • Эффективное управление памятью: связанный список выделяет память по мере роста, тогда как массивы имеют фиксированный размер (нет в Javascript; массивы в Javascript имеют динамический размер); удаление элемента из массива оставляет пустые места, которые являются пустой тратой памяти компьютера
  • Эффективная вставка/удаление: разработчик может легко вставлять или удалять узлы из связанного списка без реорганизации всей структуры данных (массивы хранят данные в памяти непрерывно, а связанные списки - нет).

Недостатки использования связанных списков вместо массивов

  • Произвольный доступ не разрешен: связанный список допускает только последовательный доступ к своим элементам, в то время как массивы допускают произвольный доступ; это замедляет поиск в связанном списке
  • Большее использование памяти на элемент: связанный список использует больше места для хранения в памяти, так как каждый узел в списке содержит как данные, так и ссылку на следующий узел.

Еще немного о массивах Javascript

Как упоминалось ранее, «массивы в Javascript немного отличаются от массивов в таких языках, как C, поскольку они имеют динамический размер. Другими словами, массивы Javascript являются разреженными, что означает, что только назначенному индексу будет присвоено значение, в то время как другим индексам в массиве не будут присвоены значения. Например, установка значения для 10 000-го индекса массива не приведет к выделению памяти для массива с 10 000 элементов. Единственный способ для массива Javascript выделить память для каждого индекса — это присвоить значение каждому индексу.

Другие преимущества и недостатки остаются в силе. Добавление или добавление элементов в начало или конец связанного списка имеет постоянную временную сложность O (1), где она O (n) для массива. Обратное верно для извлечения элемента. Временная сложность поиска составляет O (1) для массива и O (n) для связанного списка.

В следующей таблице представлена ​​временная сложность связанных списков и массивов Javascript.

Использование связанных списков в Javascript

Как разработчики Javascript, использование связанных списков требует немного больше усилий, чем использование массивов. Нам нужно действительно построить один! Сначала мы начнем с инициализации класса LinkedListNode. Как вы можете видеть ниже, каждый узел имеет некоторые данные и указатель на следующий узел в списке.

Затем, используя объектно-ориентированный подход, мы инициализируем класс LinkedList методом добавления данных в список.

Как только мы сможем добавить, нам нужно добавить метод для удаления данных из списка.

Затем мы можем добавить метод get для получения данных из связанного списка.

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

Использование класса LinkedList может выглядеть примерно так.

Вывод в терминал.

Заключение

Надеюсь, это хороший и краткий обзор связанных списков и хороший опыт для читателей. Скорее всего, в ближайшем будущем я продолжу использовать массивы в Javascript, но я уверен, что добавил еще одну фундаментальную концепцию CS в свой набор инструментов, чтобы помочь мне в моем путешествии инженера-программиста.