Java LinkedList - 직접 구현하기 2

기존에 직접 만든 LinkedList 추가로 특정 위치에 데이터 추가 및 삭제 기능을 만들도록 한다.

void add(int index, Object e)

public void add(int index, Object e) {
    Node newNode = new Node(e);

    if (index == 0) {
        newNode.next = first;
        first = newNode;
    } else {
        Node prevNode = getNode(index-1);
        newNode.next = prevNode.next;
        prevNode.next = newNode;
    }
    size++;
}
  • 인덱스 통해 데이터 추가
  • 노드 추가에는 프론트와 백 노드도 사이에 추가한다.

Object remove(int index)

public Object remove(int index) {
    Node retNode;
    Object item;
    if (index == 0) {
        retNode = first;
        first = first.next;
    } else {
        Node prevNode = getNode(index-1);
        retNode = prevNode.next;
        prevNode.next = prevNode.next.next;
    }
    item = retNode.item;
    retNode.item = null;
    retNode.next = null;
    size--;
    return item;
}
  • 인덱스 통해 데이터 삭제
  • 노드 삭제에는 프론트와 백 노드 사이에 삭제한다.


add 동작 원리 - 첫 번째 노드 추가

첫 번째 항목으로 노드 추가 하는 과정을 살펴보자.

  • 기존 노드 리스트 : [A->B->C]
    • 첫 번째 노드 D 추가
  • 추가된 노드 리스트: [D->A->B->C]

CLinkedList의 first 변수가 어떻게 노드가 이루어져 있는지 살펴보자.

신규 노드 추가하기 - add

first
+-----+
| x01 |
+--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x01               x02               x03

1. new Node("D")
+----------------+
| item   next    |
| +-----++-----+ |
| | "D" || N/A | |
| +-----++-----+ |
+----------------+
x04

신규 노드 다음 노드 연결하기

first
+-----+
| x01 |
+--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x01               x02               x03

2. x04.next = first
+----------------+
| item   next    |
| +-----++-----+ |
| | "D" || x01 | | 
| +-----++-----+ |
+----------------+
x04

first 멤버 변수 신규 노드로 할당

first
+-----+
| x04 | -> 3. x01 is Replace x04
+--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x01               x02               x03


+----------------+
| item   next    |
| +-----++-----+ |
| | "D" || x01 | | 
| +-----++-----+ |
+----------------+
x04

신규 노드 추가 최종

first
+-----+
| x04 |
+--+--+
   ↓
+--+-------------++----------------++----------------++----------------+
| item   next    || item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "D" || x01 | || | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------++----------------+
x04               x01               x02               x03



add 동작 원리 - 첫 번째 노드 삭제

첫 번째 항목으로 노드 삭제하는 과정을 살펴보자.

  • 기존 노드 리스트 : [D->A->B->C]
    • 첫번 째 노드 D 제거
  • 삭제된 노드 리스트: [A->B->C]

CLinkedList의 first 변수가 어떻게 노드가 이루어져 있는지 살펴보자.

노드 제거 대상

제거 대상: x04 노드
first
+-----+
| x04 |
+--+--+
   ↓
+--+-------------++----------------++----------------++----------------+
| item   next    || item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "D" || x01 | || | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------++----------------+
x04               x01               x02               x03

노드 제거하기 first 변수 교체

first
+-----+
| x01 | 1. x04 is Replcace x01
+--+--+
   ↓ 
+--+-------------++----------------++----------------++----------------+
| item   next    || item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "D" || x01 | || | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------++----------------+
x04               x01               x02               x03

first 멤버 변수 신규 노드로 할당

first
+-----+
| x01 |
+--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x01               x02               x03


2. 
x04.item = null
x04.next = null
+----------------+
| item   next    |
| +-----++-----+ |
| | N/A || N/A | | 
| +-----++-----+ |
+----------------+
x04

신규 노드 추가 최종

first
+-----+
| x01 |
+--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x04               x01               x02               x03


add 동작 원리 - 중간 노드 추가

첫 번째 항목으로 노드 추가 하는 과정을 살펴보자.

  • 기존 노드 리스트 : [A->B->C]
    • 중간에 노드 E 추가
  • 추가된 노드 리스트: [A->B->E->C]

CLinkedList의 first 변수가 어떻게 노드가 이루어져 있는지 살펴보자.

신규 노드 중간에 추가하기 - add

2. prev = first;
first    prev
+-----+  +-----+
| x01 |  | x01 |
+--+--+  +--+--+
   ↓
+--+-------------++----------------++----------------+
| item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------+
x01               x02               x03

1. new Node("E")
+----------------+
| item   next    |
| +-----++-----+ |
| | "E" || N/A | |
| +-----++-----+ |
+----------------+
x04
  • 신규로 추가할 노드를 생성하고, prev 변수를 추가해 first 참조 값을 복사한다.

신규 노드 다음 노드 연결하기

                  3. x02.next = x04(new Node)
                     ↓
+----------------++--+-------------+                  +----------------+
| item   next    || item   next    |                  | item   next    |
| +-----++-----+ || +-----++-----+ |                  | +-----++-----+ |
| | "A" || x02 | || | "B" || x04 | |                  | | "C" || N/A | |
| +-----++-----+ || +-----++-----+ |                  | +-----++-----+ |
+----------------++----------------+                  +----------------+
x01               x02                                 x03

                                    +----------------+
                                    | item   next    |
                                    | +-----++-----+ |
                                    | | "D" || x03 | | 
                                    | +-----++-----+ |
                                    +----------------+
                                    x04

신규 노드 추가 최종

first
+-----+
| x01 |
+--+--+
   ↓
+--+-------------++----------------++----------------++----------------+
| item   next    || item   next    || item   next    || item   next    |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
| | "A" || x02 | || | "B" || x04 | || | "E" || x03 | || | "C" || N/A | |
| +-----++-----+ || +-----++-----+ || +-----++-----+ || +-----++-----+ |
+----------------++----------------++----------------++----------------+
x01               x02               x04               x03



정리

add

  • 노드가 추가된 경우 오른쪽 노드의 인덱스를 한칸 씩 뒤로 이동한다.
    • 연결 리스트는 배열처럼 실제 index가 아니므로 처음 연결된 노드를 index 0, 그다음 노드를 index 1 가정일 뿐, index는 연결된 순서로 뜻한다.
  • 배열리스트 첫 항목에 데이터 추가한 경우 기존 데이터를 오른쪽으로 밀었으나, 연결 리스트는 새로 생성한 노드의 참조만 변경해주면 된다.
  • 연결 리스트의 첫 번째 노드 추가는 매우 빠르다. O(1) 빅오이다.

remove

  • 노드 삭제 시 오른쪽 노드 index 가 앞으로 당겨온다.
  • 배열리스트의 첫 항목이 삭제된 경우 데이터를 왼쪽으로 하나씩 밀었으나, 연결 리스트는 참조만 변경하므로 노드의 변경은 없다.
  • 연결 리스트의 첫 번째 노드 삭제는 매우 빠르다. O(1) 빅오이다.