💁🏻♀️ 전에 작성한 단일 연결 리스트와 연결되는 글 입니다.
전 글을 보지 않으면 이해되지 않는 부분은 다시 기재하였습니다.
배열
연결 리스트
단일 연결 리스트(singly Linked List)
이중 연결 리스트(Doubly Linked List)
원형 연결 리스트(Circular Linked List)
이해를 돕기 위해 예제를 통해 설명하자면,
1번 인덱스에 있는 노드를 찾고 싶을 때 당연히 앞에서부터 찾는 것이 빠르다.
하지만, 뒤에 있는(4번 인덱스(50))를 찾게 된다면 어떨까? 뒤에서 부터 찾는 것이 훨씬 빠르다.
function DoubleLinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
}
DoubleLinkedList.prototype.size = function () {
return this.length;
};
DoubleLinkedList.prototype.isEmpty = function () {
return this.length === 0;
};
DoubleLinkedList.prototype.printNode = function () {
process.stdout.write("head -> ");
for (let node = this.head; node != null; node = node.next) {
process.stdout.write(`${node.data} -> `);
}
console.log("null");
};
DoubleLinkedList.prototype.printNodeInverse = function () {
let temp = [];
process.stdout.write("null <- ");
for (let node = this.tail; node != null; node = node.prev) {
temp.push(node.data);
}
for (let i = temp.length - 1; i >= 0; i--) {
process.stdout.write(`${temp[i]} <- `);
}
console.log("tail");
};
DoubleLinkedList.prototype.append = function (value) {
let node = new Node(value);
if (this.head === null) {
this.head = node;
this.tail = node;
} else {
this.tail.next = node;
node.prev = this.tail;
this.tail = node;
}
this.length++;
};
DoubleLinkedList.prototype.insert = function (value, position = 0) {
if (position < 0 || position > this.length) {
return false;
}
let node = new Node(value),
current = this.head,
index = 0,
prev;
if (position === 0) {
if (this.head === null) {
this.head = node;
this.tail = node;
} else {
node.next = current;
current.prev = node;
this.head = node;
}
} else if (position === this.length) {
current = this.tail;
current.next = node;
node.prev = current;
this.tail = node;
} else {
while (index++ < position) {
prev = current;
current = current.next;
}
node.next = current;
prev.next = node;
current.prev = node;
node.prev = prev;
}
this.length++;
return true;
};
DoubleLinkedList.prototype.remove = function (value) {
let current = this.head,
prev = current;
while (current.data != value && current.next != null) {
prev = current;
current = current.next;
}
if (current.data != value) {
return null;
}
if (current === this.head) {
this.head = current.next;
if (this.length === 1) this.tail = null;
else this.head.prev = null;
} else if (current === this.tail) {
this.tail = current.prev;
this.tail.next = null;
} else {
prev.next = current.next;
current.next.prev = prev;
}
this.length--;
return current.data;
};
DoubleLinkedList.prototype.removeAt = function (position = 0) {
if (position < 0 || position >= this.length) {
return null;
}
let current = this.head,
index = 0,
prev;
if (position === 0) {
this.head = current.next;
if (this.length === 1) this.tail = null;
else this.head.prev = null;
} else if (position === this.length - 1) {
current = this.tail;
this.tail = current.prev;
this.tail.next = null;
} else {
while (index++ < position) {
prev = current;
current = current.next;
}
prev.next = current.next;
current.next.prev = prev;
}
this.length--;
return current.data;
};
DoubleLinkedList.prototype.indexOf = function (value) {
let current = this.head,
index = 0;
while (current != null) {
if (current.data === value) {
return index;
}
index++;
current = current.next;
}
return -1;
};