각 노드가 데이터와 포인터를 가지며, 두 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료 구조
LinkedList와 다르게 prev도 가지고 있다.
function Node(data) {
this.data = data;
this.prev = null;
this.next = null;
}
function DoubleLinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
}
size와 empty의 경우, 이전에 구현 했던 LinkedList와 크게 다르지 않다.
DoubleLinkedList.prototype.size = function() {
return this.length;
}
DoubleLinkedList.prototype.isEmpty = function() {
return this.length === 0;
}
일반 LinkedList와 다르게 역방향의 node도 출력 가능하다.
DoubleLinkedList.prototype.printNode = function() {
for (let node = this.head; node != null; node = node.next) {
process.stdout.write(`${node.data} -> `);
}
console.log("null");
}
DoubleLinkedList.prototype.printNodeInverse = function() {
for (let node = this.tail; node != null; node = node.prev) {
process.stdout.write(`${node.data} -> `);
}
console.log("null");
}
DoubleLinkedList.prototype.append = function(value) {
let node = new Node(value);
if (this.head === null) {
this.head = node;
this.tail = node;
} else {
this.head.next = node;
node.prev = this.head;
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);
let 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;
}
prev.next = node;
node.next = current;
node.prev = prev;
current.prev = node;
}
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;
}
value가 position으로 변경되었다는 것 이외에 remove와 크게 차이는 없다.
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) {
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;
}
기존 LinkedList의 indexOf와 동일하다.
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;
}
관련 전체 코드는 Git에 업로드 해두었습니다.
github_DoubleLinkedList