Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 이중 연결 리스트(Doubly Linked List)에서 요소 제거하기

연결 리스트(Linked List)에서 요소를 제거하는 작업은 생각보다 간단합니다. 핵심은 제거하고 싶은 노드에 대한 참조(reference)를 끊어버리는 것입니다. 참조가 끊긴 노드는 더 이상 리스트에 접근할 수 없게 되어 자연스럽게 제거된 것과 같아집니다.

이중 연결 리스트에서 요소를 제거할 때는 다음의 세 가지 경우를 고려해야 합니다.

요소 제거의 3가지 경우

1. 헤드(Head)에서 제거

첫 번째 요소를 제거하는 경우입니다. head = head.next로 헤드 포인터를 다음 노드로 옮기고, 새로운 헤드가 된 노드의 prev 링크를 null로 설정하면 됩니다. 이렇게 하면 기존 첫 번째 노드에 대한 참조가 사라지고, 헤드는 두 번째 요소부터 시작하게 됩니다.

2. 테일(Tail)에서 제거

마지막 요소를 제거하는 경우입니다. 뒤에서 두 번째 노드의 next 값을 null로 설정하면 마지막 노드와의 연결이 끊어집니다. 그리고 tail 포인터를 새로운 마지막 노드(기존의 뒤에서 두 번째 노드)로 업데이트해 주어야 합니다.

3. 중간에서 제거

리스트 중간에 있는 요소를 제거하는 경우가 가장 까다롭습니다. 이때는 제거하려는 노드의 이전 노드가 제거하려는 노드의 다음 노드를 직접 가리키도록 연결을 재구성해야 합니다. 즉, prevNode.next = node.nextnode.next.prev = prevNode 두 줄의 코드로 앞뒤 노드를 서로 연결해 주면 해당 노드는 리스트에서 빠지게 됩니다.

다음 그림은 이 과정을 시각적으로 보여줍니다.

JavaScript로 이중 연결 리스트(Doubly Linked List)에서 요소 제거하기

구현 예제

위 내용을 바탕으로 remove 메서드를 구현한 코드입니다. 위치 값(position)에 따라 헤드 제거, 테일 제거, 중간 제거를 분기 처리합니다.

remove(data, position = 0) {
    if (this.length === 0) {
        console.log("List is already empty");
        return;
    }
    this.length--;
    let currNode = this.head;
    if (position <= 0) {
        // 헤드 제거
        this.head = this.head.next;
        this.head.prev = null;
    }
    else if (position >= this.length - 1) {
        // 테일 제거
        this.tail = this.tail.prev;
        this.tail.next = null;
    }
    else {
        // 중간 제거
        let iter = 0;
        while (iter < position) {
            currNode = currNode.next;
            iter++;
        }
        currNode.next = currNode.next.next;
        currNode.next.prev = currNode;
    }
    return currNode;
}

실행 예시

실제로 동작을 확인해 보겠습니다. 리스트에 요소를 삽입한 후 특정 위치의 요소를 제거하고 결과를 출력합니다.

let list = new LinkedList();
list.insert(10);
list.insert(20);
list.insert(30);
list.remove(1);
list.display();
list.insert(15, 2);
list.remove();
list.display();

출력 결과

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

20 <->
30 <->
30 <->
15 <->

이처럼 이중 연결 리스트는 양방향 포인터(prev, next)를 모두 관리해야 한다는 점만 유의하면, 단일 연결 리스트와 마찬가지로 O(1)~O(n) 시간 안에 손쉽게 요소를 제거할 수 있습니다.