자바스크립트로 자료구조를 구현해보자.
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;
}
}