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

Введение в Связанный список (реализация Java)

Введение в Связанный список. Как реализовать связанный список в Java, Операции со связанными списками, Связанный список против массива, Операции со связанными списками сложность по времени Большая-O

Автор оригинала: Pankaj Kumar.

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

Каждый элемент в связанном списке называется “Узлом”. Каждый узел содержит элемент данных и следующий узел, который указывает на следующий узел в связанном списке.

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

Зачем нам нужен Связанный список?

Хотя вы, должно быть, видели структуру данных массивов ранее, они тоже являются линейной структурой данных, но они создают определенные ограничения, такие как:

  • Они статичны по своей природе, и поэтому их размер не может быть изменен.
  • Им нужна непрерывная память для хранения своих ценностей.

Для устранения этих ограничений Связанный список предлагает следующие функции:

  1. ДИНАМИЧЕСКОЕ ВЫДЕЛЕНИЕ ПАМЯТИ т. е. выделение памяти выполняется во время выполнения компилятором.
  2. Каждый отдельный узел может иметь любой блок памяти, и он связан с другими узлами по адресу блока, поэтому не требуется никаких смежных блоков памяти.

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

  • Класс связанного списка содержит узел частного класса и объект класса Узла (называемый как Head) в качестве одного из его свойств.
  • Заголовок узла указывает на начало Связанного списка.
  • Каждый узел содержит элемент данных и следующий узел, который указывает на следующий узел в Связанном списке.
  • Последние узлы указывают на нуль.
  • В более новых вариантах у нас также есть элемент хвостового узла, который помогает нам сократить трудоемкость операций, которые необходимо легко выполнять.

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

Реализация связанного списка должна иметь следующие методы общего назначения.

  1. get First : Он возвращает данные (если таковые имеются, иначе он создает исключение), присутствующие на первом узле. Он просто возвращает ” this.head.данные “предоставлены” если(это.) “, т. е. если размер связанного списка не равен нулю.
  2. get Last : Он возвращает данные (если таковые имеются, иначе он создает исключение), присутствующие на последнем узле. Он просто возвращает ” this.tail.data “при условии” если(это.) “, т. Е. если размер связанного списка не равен нулю.
  3. get At : В качестве аргумента используется целочисленный индекс, и если индекс допустим(т. Е. Если и индекс <размер связанного списка), он getNodeAt : В качестве аргумента он принимает целочисленный индекс, и если индекс допустим(т. Е. Если и индекс <размер связанного списка), он возвращает
  4. Узел по этому индексу. addLast : Он принимает ввод типа связанного списка, а затем добавляет его в последнюю позицию связанного списка, тем самым увеличивая размер на “+1” и указывая “хвост” на недавно добавленный узел.
  5. addFirst : Он принимает ввод типа связанного списка, а затем добавляет его в первую позицию связанного списка, тем самым увеличивая размер на “+1” и указывая “головку” на недавно добавленный узел.
  6. addAt : Он принимает входные данные типа Связанного списка, а также принимает в качестве аргументов целочисленный индекс (пусть он равен “k”), а затем добавляет его (данные) в k-ю позицию связанного списка, тем самым увеличивая размер на “+1”. В случае, если добавляемый элемент “
  7. Первый ” или ” Последний “, он вызывает ” addFirst ” или ” addLast ” соответственно. removeFirst : Он удаляет первый элемент связанного списка (при условии, что список не является пустым списком, в котором он создает исключение) и перемещает “заголовок”, чтобы указать на 2
  8. nd элемент (если таковой имеется ) и уменьшает размер на “1”. Кроме того, он возвращает удаленные данные. removeLast : Он удаляет последний элемент связанного списка (при условии, что список не является пустым списком, в котором он создает исключение) и перемещает “хвост”, указывая на 2
  9. nd последний элемент (если таковой имеется), и уменьшает размер на “1”. Кроме того, он возвращает удаленные данные. RemoveAt : В качестве аргумента он принимает целочисленный индекс (скажем, k), и если индекс допустим(т. Е. Если и индекс <размер связанного списка), удаляет “k-й” элемент связанного списка (при условии, что список не является пустым списком, в котором он создает исключение) и уменьшает размер на “1”. Кроме того, он возвращает удаленные данные. В случае, если удаляемый элемент “
  10. Первый ” или ” Последний “, он вызывает ” удалить первым ” или ” Удалить последний ” соответственно. display : Этот метод выводит весь связанный список, проходя его один раз, начиная с указателя, указывающего на “head”, пока он не укажет на “null”.

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

package com.journaldev.ds;

public class LinkedList {

	private class Node {

		int data;

		Node next;

	}

	private Node head;

	private Node tail;

	private int size;

	public int size() {

		return this.size;

	}

	public int getFirst() throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is Empty.");

		}

		return this.head.data;

	}

	public int getLast() throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is Empty.");

		}

		return this.tail.data;

	}

	public int getAt(int idx) throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is Empty.");

		}

		if (idx < 0 || idx >= this.size) {

			throw new Exception("Invalid Index.");

		}

		Node temp = this.head;

		for (int i = 1; i <= idx; i++) {

			temp = temp.next;

		}

		return temp.data;

	}

	private Node getNodeAt(int idx) throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is Empty.");

		}

		if (idx < 0 || idx >= this.size) {

			throw new Exception("Invalid Index.");

		}

		Node temp = this.head;

		for (int i = 1; i <= idx; i++) {

			temp = temp.next;

		}

		return temp;

	}

	public void addLast(int item) {

		// create

		Node nn = new Node();

		nn.data = item;

		nn.next = null;

		// attach

		if (this.size > 0)

			this.tail.next = nn;

		// dm update

		if (this.size == 0) {

			this.head = nn;

			this.tail = nn;

			this.size += 1;

		} else {

			this.tail = nn;

			this.size += 1;

		}

	}

	public void addFirst(int item) {

		// create

		Node nn = new Node();

		nn.data = item;

		nn.next = null;

		// attach

		nn.next = this.head;

		// dm update

		if (this.size == 0) {

			this.head = nn;

			this.tail = nn;

			this.size++;

		} else {

			this.head = nn;

			this.size++;

		}

	}

	public void addAt(int item, int idx) throws Exception {

		if (idx < 0 || idx > this.size) {

			throw new Exception("Invalid Index.");

		}

		if (idx == 0) {

			addFirst(item);

		} else if (idx == this.size) {

			addLast(item);

		} else {

			// create

			Node nn = new Node();

			nn.data = item;

			nn.next = null;

			// attach

			Node nm1 = getNodeAt(idx - 1);

			Node np1 = nm1.next;

			nm1.next = nn;

			nn.next = np1;

			// dm

			this.size++;

		}

	}

	public int removeFirst() throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is empty.");

		}

		Node temp = this.head;

		if (this.size == 1) {

			this.head = null;

			this.tail = null;

			this.size = 0;

		} else {

			this.head = this.head.next;

			this.size--;

		}

		return temp.data;

	}

	public int removeLast() throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is empty.");

		}

		Node temp = this.tail;

		if (this.size == 1) {

			this.head = null;

			this.tail = null;

			this.size = 0;

		} else {

			Node sm2 = getNodeAt(this.size - 2);

			sm2.next = null;

			this.tail = sm2;

			this.size--;

		}

		return temp.data;

	}

	public int removeAt(int idx) throws Exception {

		if (this.size == 0) {

			throw new Exception("LL is empty.");

		}

		if (idx < 0 || idx >= this.size) {

			throw new Exception("Invalid Index.");

		}

		if (idx == 0) {

			return removeFirst();

		} else if (idx == this.size - 1) {

			return removeLast();

		} else {

			Node nm1 = getNodeAt(idx - 1);

			Node n = nm1.next;

			Node np1 = n.next;

			nm1.next = np1;

			this.size--;

			return n.data;

		}

	}

	public void display() {

		System.out.println("----------------------");

		Node temp = this.head;

		while (temp != null) {

			System.out.print(temp.data + " ");

			temp = temp.next;

		}

		System.out.println(".");

		System.out.println("----------------------");

	}

	public static void main(String[] args) throws Exception {

		LinkedList list = new LinkedList();

		list.addLast(10);

		list.addLast(20);

		list.addLast(30);

		list.addLast(40);

		// this will display the list

		list.display();

		// first element i.e.10 should be printed

		System.out.println(list.getFirst());

		// last element i.e.40 should be printed

		System.out.println(list.getLast());

		// element at 3rd index i.e.40 should be printed

		System.out.println(list.getAt(3));

		// a memory address of a node should be printed

		System.out.println(list.getNodeAt(3));

		// 10 should be removed and printed

		System.out.println(list.removeFirst());

		// 40 should be removed and printed

		System.out.println(list.removeLast());

		// list without 10 and 40 should be printed

		list.display();

		// 100 should be added at first

		list.addFirst(100);

		list.display();

		// 30 should be removed

		list.removeAt(2);

		// 300 should be added at 2nd index

		list.addAt(300, 2);

		list.display();

	}

}

Выход

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

ПРИМЕЧАНИЕ: Java обеспечивает реализацию LinkedList. Для фактического программирования используйте официальную реализацию.

Java LinkedList – Список ссылок На Java

Сложность Операций со Связанными Списками

getFirst O(1)
получить Последнее O(1) {Примечание: Это потому , что у нас тоже есть указатель “хвост”, иначе это было бы O(n) }
добраться До O(n)
Приготовьтесь к обеду O(n)
addLast O(1) {Примечание: Это потому , что у нас тоже есть указатель “хвост”, иначе это было бы O(n) }
Добавить сначала O(1)
добавить O(n)
Удалить первым O(1)
Удалить последние O(1) {Примечание: Это потому , что у нас тоже есть указатель “хвост”, иначе это было бы O(n) }
удалить O(n)
Дисплей O(n)

Вывод

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