연결 리스트는 순서가 지정된 데이터 요소의 모음이다. 연결 리스트에서는 데이터 요소는 노드로 표시합니다. 각 노드는 데이터와 다음 노드에 대한 포인터로 구성되어 있습니다.
연결 리스트의 종류에는 몇 가지 유형이 있습니다. 대표적인 것들로 단일, 이중, 원형 연결 리스트가 있습니다.
단일 연결 리스트란 단일 방향(포인터)을 가진 리스트를 말합니다. 포인터를 이용해 다음 순서의 노드를 가리켜주고, 이를 통해 머리부터 끝까지 탐색을 할 수 있습니다.
이중 연결 리스트란 이중 방향(포인터)를 가진 리스트를 말합니다. 이 전의 단일 연결 리스트는 특정 방향의 포인터 1개였지만 이중 연결 리스트는 이전 노드, 다음 노드를 둘다 가리키는 포인터를 가지고 있습니다. 그래서 양쪽으로 탐색이 가능하다는 장점이 있습니다.
원형 연결 리스트는 이 전에 해왔던 단일 연결 리스트나 이중 연결 리스트에서 끝을 처음과 연결된 리스트를 말합니다. 원형 리스트(단일 연결 리스트로 표현)는 모든 포인터가 다음 노드로 연결되어 있습니다. 즉 다시 마지막에서 첫번째로 이동하지 않아도 다음 노드가 첫번째 노드를 가리킵니다.
class Node {
constructor (value, prev, next) {
this.value = value
this.next = next || null
this.prev = prev || null
}
}
class LinkedList {
constructor () {
this.head = this.tail = null
}
// 꼬리 뒤 쪽에 데이터 추가하기
append(value) {
// 빈 리스트일 때
if (!this.tail) {
this.head = this.tail = new Node(value)
}
// 리스트에 노드가 하나 이상일 때
else {
let oldTail = this.tail
this.tail = new Node(value)
oldTail.next = this.tail
this.tail.prev = oldTail
}
}
// 헤드 앞 쪽에 데이터 추가하기
prepend(value) {
// 빈 리스트일 때
if (!this.head) {
this.head = this.tail = new Node(value)
}
// 리스트에 노드가 하나 이상일 때
else {
let oldHead = this.head
this.head = new Node(value)
oldHead.prev = this.head
this.head.next = oldHead
}
}
}
class LinkedList {
constructor () {
this.head = this.tail = null
}
deleteHead() {
// 빈 리스트일 때
if (!this.head) {
return null
}
// 리스트에 노드가 하나 이상일 때
else {
let removedHead = this.head
// 리스트에 노드가 하나 밖에 없을 때
if (this.head === this.tail) {
this.head = this.tail = null
}
// 리스트에 노드가 하나보다 많을 때
else {
this.head = this.head.next
this.head.prev = null
}
return removedHead.value
}
}
deleteTail() {
// 빈 리스트일 때
if (!this.tail) {
return null
}
// 리스트에 노드가 하나 이상일 때
else {
let removedTail = this.tail
// 리스트에 노드가 하나 밖에 없을 때
if (this.head === this.tail) {
this.tail = this.head = null
}
// 리스트에 노드가 하나보다 많을 때
else {
this.tail = this.tail.prev
this.tail.next = null
}
return removedTail.value
}
}
}
class LinkedList {
constructor () {
this.head = this.tail = null
}
search(value) {
let currentNode = this.head
while (currentNode) {
if (currentNode.value === value) {
return currentNode
}
currentNode = currentNode.next
}
return null
}
}