Введение

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

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

Определение связанного списка

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

Типы связанных списков:

Существуют различные типы связанных списков, например:

  • Односвязный список. Каждый узел содержит ссылку на следующий узел.
  • Двухсвязный список. Каждый узел содержит ссылки как на следующий, так и на предыдущий узлы.
  • Круговой связанный список. Последний узел в списке указывает на первый узел, образуя петлю.

Реализация связанного списка в Java

Создание класса узла

Класс Node является основой связанного списка, поскольку он представляет отдельные элементы в списке. Вот пример простого класса Node в Java:

public class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

Создание класса связанного списка

Класс Linked List содержит методы для добавления, удаления и отображения элементов. Вот базовый класс связанного списка в Java:

public class LinkedList {
    Node head;

    public LinkedList() {
        head = null;
    }

    // Methods for adding, removing, and displaying elements go here
}

Общие операции со связанными списками

Добавление элементов

Чтобы добавить элементы в связанный список, вы можете вставить их в начало, конец или определенный индекс. Вот примеры кода для каждого сценария:

Добавление в начале

public void addFirst(int data) {
    Node newNode = new Node(data);
    newNode.next = head;
    head = newNode;
}

Добавление в конце

public void addLast(int data) {
    Node newNode = new Node(data);

    if (head == null) {
        head = newNode;
        return;
    }

    Node last = head;
    while (last.next != null) {
        last = last.next;
    }
    last.next = newNode;
}

Добавление по определенному индексу

public void addAtIndex(int index, int data) {
    if (index == 0) {
        addFirst(data);
        return;
    }

    Node newNode = new Node(data);
    Node current = head;

    for (int i = 0; i < index - 1; i++) {
        if (current == null) {
            throw new IndexOutOfBoundsException("Invalid index");
        }
        current = current.next;
    }

    newNode.next = current.next;
    current.next = newNode;
}

Удаление элементов

Чтобы удалить элементы из связанного списка, вы можете удалить первое вхождение, последнее вхождение или определенный индекс. Вот примеры кода для каждой ситуации:

Удаление первого вхождения

public void removeFirstOccurrence(int data) {
    if (head == null) {
        return; // List is empty
    }

    if (head.data == data) {
        head = head.next;
        return;
    }

    Node current = head;
    while (current.next != null) {
        if (current.next.data == data) {
            current.next = current.next.next;
            return;
        }
        current = current.next;
    }
}

Удаление последнего вхождения

public void removeLastOccurrence(int data) {
    Node lastOccurrence = null;
    Node current = head;
    int index = 0, lastIndex = -1;

    while (current != null) {
        if (current.data == data) {
            lastOccurrence = current;
            lastIndex = index;
        }
        current = current.next;
        index++;
    }

    if (lastOccurrence != null) {
        removeAtIndex(lastIndex);
    }
}

Удаление по определенному индексу

public void removeAtIndex(int index) {
    if (head == null) {
        return; // List is empty
    }

    if (index == 0) {
        head = head.next;
        return;
    }

    Node current = head;
    for (int i = 0; i < index - 1; i++) {
        if (current == null || current.next == null) {
            throw new IndexOutOfBoundsException("Invalid index");
        }
        current = current.next;
    }

    current.next = current.next.next;
}

Поиск и доступ к элементам

Для поиска элементов в связанном списке и доступа к ним по индексу вы можете использовать следующие методы:

Поиск элемента

public boolean contains(int data) {
    Node current = head;
    while (current != null) {
        if (current.data == data) {
            return true;
        }
        current = current.next;
    }
    return false;
}

Доступ к элементу по индексу

public int get(int index) {
    Node current = head;
    for (int i = 0; i < index; i++) {
        if (current == null) {
            throw new IndexOutOfBoundsException("Invalid index");
        }
        current = current.next;
    }
    return current.data;
}

Обход связанного списка

Обход связанного списка включает в себя итерацию по его элементам. Для этой цели вы можете использовать цикл или встроенный в Java итератор:

Обход с помощью цикла

public void display() {
    Node current = head;
    while (current != null) {
        System.out.print(current.data + " -> ");
        current = current.next;
    }
    System.out.println("null");
}

Заключение

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

Понравилось читать? Еще не являетесь участником Medium? Вы можете поддержать мою работу напрямую, зарегистрировавшись по моей реферальной ссылке здесь. Это быстро, просто и не требует дополнительных затрат. Спасибо за вашу поддержку!