LinkedList는 데이터 구조 중 하나로, 각 데이터를 저장하는 노드(Node)
들이 연결된 형태로 구성됩니다. 각 노드는 두 가지 요소를 가지고 있습니다. 하나는 실제 데이터
, 다른 하나는 다음 노드를 가리키는 포인터(참조)
입니다. 이 구조는 데이터를 순차적으로 연결하는 방식으로 , 특정 상황에서 매우 유용합니다.
다음 노드의 주소
를 가리키는 참조입니다.Null
이 됩니다.순차적
으로 이루어집니다.빠른 삽입과 삭제
연결 리스트에서 노드의 삽입과 삭제는 배열보다 더 효율적입니다. 배열에서는 삽입이나 삭제 후 나머지 요소들을 이동
시켜야 하지만, 연결 리스트는 다음 노드의 주소를 가르키는 포인터만 수정
하면 되기 때문에 데이터 이동이 없어 효율적
입니다.
특정 위치에서 삽입 또는 삭제하는 연산은 O(1)
시간 복잡도를 가집니다.
단, 삽입/삭제 위치를 찾는 데 O(n)
시간이 필요할 수 있습니다.
동적 크기 조절
연결 리스트는 배열과 달리 미리 크기를 정할 필요가 없습니다. 필요한 만큼 노드를 동적으로 할당하고 연결할 수 있어, 메모리를 효율적으로 사용할 수 있습니다.
느린 탐색 속도
배열과 달리, 연결 리스트는 인덱스가 없기 때문에 특정 위치의 요소에 접근하기 위해서는 첫 노드부터 순차적으로 탐색해야 합니다. 이는 탐색 속도를 저하
시킵니다.
요소를 찾기 위해 전체 리스트를 탐색해야 하므로 , 최악의 경우 O(n
)시간이 소요됩니다. 리스트가 길어질수록 성능에 큰 영향을 미칩니다.
추가적인 메모리 사용
연결 리스트는 데이터 외에도 다음 노드를 가리키는 포인터를 유지
해야합니다. 그렇기에 배열에 비해 더 많은 메모리를 사용합니다. 특히 이중 연결 리스트의 경우 각 노드가 두 개의 포인터(이전 , 다음 노드)를 가져야 하므로 더 많은 메모리가 필요합니다.
생활 코딩님의 강좌를 보면서 구현을 해보았습니다. 구현을 하면서 느낀점은 노드의 추가 ,삭제시 노드들의 연결을 지정해 주는것이 중요하다라는 것이었습니다.
<Linked List 구현 클래스>
package Linked_list;
public class LinkedList {
private Node head; //맨 처음 노드
private Node tail; //맨 마지막 노드
private int size = 0;
//Node 클래스 : 데이터와 다음 노드의 주소를 저장할수 있어야 한다
private class Node {
private Object data; //저장할 데이터 값
private Node next; // 다음 노드를 가르킨다
public Node(Object input) {
this.data = input;
this.next = null;
}
}
//addFirst 메서드 : 최초 노드를 생성하는 메서드
public void addFirst(Object input) {
Node newNode = new Node(input);
newNode.next = head;
head = newNode;
size++;
if (head.next == null) {
tail = head;
}
}
//addLast 메서드 : 데이터가 하나 이상일때, 마지막 노드를 생성하는 메서드
public void addLast(Object input){
Node newNode = new Node(input);
if (size == 0) {
addFirst(input);
} else {
tail.next = newNode;
tail = newNode;
size++;
}
}
//노드를 탐색하는 메서드
Node node(int index) {
Node x = head;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
}
//노드를 인덱스 위치에 추가하는 메서드
public void add(int index, Object input) {
//맨앞에 노드를 추가하는 경우
if (index == 0) {
addFirst(input);
}else{
Node newNode = new Node(input); //새로 추가된 노드
Node temp1 = node(index - 1); //추가될 노드 인덱스 이전 위치 노드
Node temp2 = temp1.next; //추가될 노드 인덱스 다음 위치의 노드
temp1.next = newNode; //노드 연결
newNode.next = temp2; //노드 연결
}
}
//첫번쨰 노드부분을 지우는 메서드
public Object removeFirst(){
Node temp = head;
head = head.next;
Object returnData = temp.data;
temp = null;
size--;
return returnData;
}
//인덱스 위치의 노드를 삭제하는 메서드
public Object remove(int index) {
if (index == 0) {
return removeFirst();
}
Node temp = node(index - 1);
Node todoDelted = temp.next;
temp.next = temp.next.next;
Object retrunData = todoDelted.data;
if (temp.next == tail) {
tail = temp;
}
return retrunData;
}
//리스트 값을 출력하는 메서드
public String toString() {
if (head == null) {
return "[]";
}
Node temp = head;
String str = "[";
while (temp.next != null) {
str += temp.data + ", ";
temp = temp.next;
}
str += temp.data;
return str + "]";
}
}
<Main 클래스>
package Linked_list;
public class Main {
public static void main(String[] args) {
LinkedList numbers = new LinkedList();
numbers.addLast(10);
numbers.addLast(20);
numbers.addLast(30);
numbers.addFirst(5);
numbers.add(1,15);
//리스트 전체 값 출력
System.out.println(numbers);
//맨앞의 삭제된 값 출력
System.out.println(numbers.removeFirst());
//리스트 전체 값 출력
System.out.println(numbers);
//원하는 인덱스의 삭제된 값 출력 (20)
System.out.println(numbers.remove(2));
//리스트 전체 값 출력
System.out.println(numbers);
}
}
도움 받은 출처 : https://www.youtube.com/watch?v=sq49IpxBl2k&list=PLuHgQVnccGMDsWOOn_P0EmAWB8DArS3Fk&index=20