자바스크립트로 자료구조를 구현해보자.

Linked List에서 사용할 Node 구현 🌞

export default class LinkedListNode {
    constructor(value, next = null) {
        this.value = value;
        this.next = next;
    }

    toString(callback) {
        return callback ? callback(this.value) : `${this.value}`;
    }
}

Linked List 구현 🌞

import LinkedListNode from './LinkedListNode';
import Comparator from '../../utils/comparator/Comparator';

export default class LinkedList {
    constructor(comparatorFunction) {
        this.head = null;
        this.tail = null;
        this.compare = new Comparator(comparatorFunction);  
    }

    prepend(value) { // 새로운 노드를 가장 앞에 추가하는 메서드
        const newNode = new LinkedListNode(value, this.head);
        this.head = newNode;

        if (!this.tail) {
            this.tail = new Node
        }

        return this;
    }

    append(value) { // 리스트 가장 뒤에 새로운 노드를 추가하는 메서드
        const newNode = new LinkedListNode(value);

        if (!this.head) {
            this.head = newNode;
            this.tail = newNode;
            return this;
        }

        this.tail.next = newNode;
        this.tail = newNode;
        return this;
    }

    delete(targetValue) {
        if (!this.head) return null;

        let deletedNode = null;

        // targetValue를 value로 갖지 않는 노드를 Head로 찾을 때까지 순회
        while (this.head && this.compare.equal(this.head.value, targetValue)) {
            deletedNode = this.head;
            this.head = this.head.next;
        }

        let currentNode = this.head;

        if (currentNode !== null) {
            while (currentNode.next) {
                if (this.compare.equal(currentNode.next.value, targetValue)) {
                    deletedNode = currentNode.next;
                    currentNode.next = currentNode.next.next;
                } else {
                    currentNode = currentNode.next;
                }
            }
        }

        // tail node도 삭제해야 하는지 확인
        if (this.compare.equal(this.tail.value, targetValue)) {
            this.tail = currentNode;
        }

        return deletedNode;
    }

    find({ value = undefined, callback = undefined }) {
        if (!this.head) return null;

        let currentNode = this.head;
        while (currentNode) {
            if (callback && callback(currentNode.value)) {
                return currentNode;
            }

            if (value !== undefined && this.compare.equal(currentNode.value, value)) {
                return currentNode;
            }

            currentNode = currentNode.next;
        }

        return null;
    }

    deleteTail() {
        const deletedTail = this.tail;

        if (this.head === this.tail) {
            this.head = null;
            this.tail = null;

            return deletedTail;
        }

        let currentNode = this.head;
        while (currentNode.next) {
            if (!currentNode.next.next) {
                current.next = null;
            } else {
                currnetNode = currentNode.next;
            }
        }

        this.tail = currentNode;
        return deletedTail;
    }

    deleteHead() {
        if (!this.head) return null;

        const deletedHead = this.head;
        if (this.head.next) {
            this.head = this.head.next;
        } else {
            this.head = null;
            this.tail = null;
        }

        return deletedHead;
    }

    // 여러 노드 추가
    fromArray(values) {
        values.forEach((value) => this.append(value));
        return this;
    }

    toArray() {
        const nodes = [];
        let currentNode = this.head;
        while (currentNode) {
            nodes.push(currentNode);
            currentNode = currentNode.next;
        }

        return nodes;
    }

    toString(callback) {
        return this.toArray().map((node) => node.toString(callback)).toString();
    }

    reverse() {
        let currNode = this.head;
        let prevNode = null;
        let nextNode = null;

        while (currNode) {
            nextNode = currNode.next;
            currNode.next = prevNode;
            prevNode = currNode;
            currNode = nextNode;
        }

        this.tail = this.head;
        this.head = prevNode;

        return this;
    }
}

코드 출처