Структура данных - это способ хранения и организации данных. Как вы организуете эти данные, зависит от вас.

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

Сегодня мы поговорим о структурах данных Singly Linked List и о том, как реализовать их в JavaScript. Односвязный список - это набор узлов, каждый из которых имеет прямую ссылку на следующий узел в коллекции. Первый узел в списке называется заголовком, а последний узел в списке называется хвостом.

Класс узла

Узел можно визуализировать как один из «прямоугольников» на схеме, представленной выше. Узел - это простой объект JavaScript с двумя свойствами.

данные: значение узла

следующий: прямая ссылка на следующий узел в списке.

Начнем с реализации узла в JavaScript. Я буду использовать классы для реализации односвязного списка. Вы также можете использовать функции, но я просто предпочитаю использовать класс для своего шаблона.

Приведенный выше код создает класс узла с конструктором, он получает данные, которые являются значением, которое будет храниться в узле. Следующее свойство по умолчанию - null, потому что мы еще не знаем, какой следующий узел находится в списке.

LinkedList Класс

Хорошо, теперь, когда мы можем создавать узлы с данными, нам нужно где-то разместить эти узлы. Давайте создадим класс связанного списка.

Приведенный выше код создает класс LinkedList с конструктором, конструктор не получает аргументов. По умолчанию для головы и хвоста установлено значение null. Для свойства length по умолчанию установлено значение «0», поскольку в списке нет узлов.

Хорошо, у нас есть два класса: один для создания узлов, а другой для их хранения. Но как нам точно сохранить узел в списке? Что ж, для этого нам нужны методы с функциональностью.

Методы

Мы добавим шесть методов в класс LinkedList.

push (значение) - Добавить узел в конец связанного списка

pop () - Удаляет узел из конца связанного списка

get (index) - возвращает узел по указанному индексу

delete (index) - Удалить узел по указанному индексу

isEmpty () - возвращает истину или ложь в зависимости от длины списка

print () - возвращает видимое представление связанного списка

Я напишу все методы отдельно для чистоты, обратите внимание, что все эти методы находятся в классе LinkedList.

Метод push

Давайте рассмотрим первый метод в списке выше, push (). Таким образом мы можем поместить узлы в LinkedList.

Метод push добавляет узел в конец списка. Это один из самых простых способов реализовать. Метод push получает один аргумент - значение узла.

Вот что он должен делать.

  1. Создать новый узел
  2. Проверьте, существует ли голова, если нет, то узел - это и хвост, и голова.
  3. Установите свойство current tails next для нового узла, так как новый узел будет добавлен в конец списка.
  4. Установите хвост на новый узел.
  5. Увеличить свойство длины

Вот как мы это делаем в JavaScript:

Метод isEmpty

Замечательно, теперь у нас есть возможность добавлять узлы в связанный список. Давайте реализуем метод isEmpty. Это очень просто :)

Вот что он должен делать:

  1. Вернуть истину или ложь в зависимости от длины списка

Вот как мы это делаем в JavaScript:

Поп-метод

Метод pop немного сложнее, поскольку нам нужно знать предпоследний узел, чтобы вытолкнуть последний узел в списке. На этом этапе вы можете спросить, почему я не могу просто получить доступ к последнему индексу или другим методам, которые я использовал ранее для массива?

Одним из недостатков связного списка является обход, вам нужно начинать с головного узла и перемещаться по каждому узлу в списке. Вы не можете просто использовать arr [2] для доступа к узлу в списке. Я расскажу о некоторых преимуществах и недостатках связанного списка в конце этой статьи.

Вот что должен делать метод pop:

  1. Вернуть null, если список пуст
  2. Если голова является хвостом, установите для головы и хвоста значение null. Уменьшить длину списка и вернуть хвост
  3. Найдите предпоследний узел и установите для его следующего свойства значение null.
  4. Установите хвост на предпоследний узел
  5. Уменьшить длину и вернуть удаленный узел

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

Нам нужно найти предпоследний узел и присвоить его следующему свойству значение null, теперь старый хвост будет удален, а предпоследний станет новым хвостом.

Вот как мы это делаем в JavaScript:

Метод get

Метод get получает один аргумент - индекс. Вот что он должен делать:

  1. Если index равен 0, вернуть голову
  2. Если индекс меньше 0 или индекс больше длины списка, вернуть null
  3. Найдите и верните узел по указанному индексу

Вот как мы это делаем в JavaScript:

Метод удаления

Метод удаления получает один аргумент - индекс. Вот что он должен делать:

  1. Если index равен 0, установите свойство next для текущего узла в начало. (следующий узел в списке станет новой головой). Уменьшите длину и верните удаленный узел.
  2. Если индекс меньше 0 или индекс больше длины списка, вернуть null
  3. Найдите узел перед узлом, который необходимо удалить, установите для его следующего свойства следующее свойство узла, который необходимо удалить.
  4. Уменьшите свойство длины и верните удаленный узел

Вот как мы это делаем в JavaScript:

Метод печати

Последний метод, который мы собираемся реализовать, - это метод печати. Это скорее визуальный помощник, чем предоставление каких-либо функций структуре данных.

Вот что он должен делать:

  1. Вернуть все узлы, соединенные стрелкой

Вот как мы это делаем в JavaScript:

Если бы у нас было три узла в связанном списке, A, B и C. Теперь мы можем визуализировать, что происходит, следующим образом: «A =› B = ›C

Полная реализация

Как мы его используем?

Все, что вам нужно сделать, это создать переменную и назначить ее новому экземпляру класса LinkedList.

Теперь просто используйте эту переменную и методы, предоставленные в классе LinkedList.

Заключительное заявление

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

Хорошим вариантом использования структуры данных связанного списка может быть музыкальный проигрыватель. Если пользователь нажимает следующую кнопку, вы перемещаете следующую песню в списке. Узел может быть песней, а его следующее свойство может быть ссылкой на следующую песню в списке.

Напишите мне в Twitter, если у вас есть какие-либо вопросы или вы просто хотите поговорить о коде и структурах данных!