[TypeScript] 자료 구조로 담아내기. #12 - 연결 리스트(with. null 노드)
![[TypeScript] 자료 구조로 담아내기. #12 - 연결 리스트(with. null 노드)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2F5v235ueAU58%2Fupload%2F265377fe2e8da28d69701f873c907dc4.jpeg&w=3840&q=75)
이번 편은 이전 편으로부터 이어집니다.
조금 예리하신 분들은 이전 편에서 다룬 헤드 노드만으로는 충분치 않다는 것을 느끼셨을 것입니다. 최소한 첫 노드에 예외를 부여하는 상황은 피했으나 후임자가 null임을 확인하는 구현 또한 만족스럽지는 않습니다.
카이로의 코끼리
카이로의 코끼리에 대해 알고 계십니까? 링크를 통해 확인하실 수 있습니다. 꽤 재밌으므로 한번 읽어 보시길 추천합니다. 여기서 중요한 아이디어는 끝 위치에 미리 코끼리를 둔다는 것입니다. 즉, 단일 연결 리스트의 경우엔 끝을 의미하는 센티넬 노드를 두는 것으로 해석할 수 있습니다.
null 노드
null 노드는 전역적으로 사용되는 불변 객체이므로 아래와 같이 생성합니다.
class SinglyLinkedListNullNode<T> implements SinglyLinkedListNode<T> {
private static nullNode?: SinglyLinkedListNullNode<any>;
private constructor() {}
static get(): SinglyLinkedListNullNode<any> {
if(!this.nullNode) { this.nullNode = new SinglyLinkedListNullNode(); }
return this.nullNode;
}
// ...
}
외부에서 구분하기 위해 아래와 같은 연산을 추가합니다. 이는 null 노드이면 true, 그 외에는 모두 false를 반환합니다.
interface SinglyLinkedList<T> {
isNull(): boolean;
// ...
}
null 노드는 그저 종료자 역할만 수행하는 것으로 충분합니다. 일종의 null 오브젝트 패턴의 예로 볼 수 있습니다.
class SinglyLinkedListNullNode<T> implements SinglyLinkedListNode<T> {
linkBefore(succ: SinglyLinkedListNode<T>): void {
}
unlink(pred: SinglyLinkedListNode<T>): void {
}
next(): SinglyLinkedListNode<T> {
return this;
}
get(): T {
throw new ReferenceError("...");
}
set(element: T): void {
throw new ReferenceError("...");
}
access(index: number): SinglyLinkedList<T> {
return this;
}
getFirst(): T {
return this.get();
}
setFirst(element: T): void {
this.set(element);
}
insertFirst(element: T): SinglyLinkedList<T> {
throw new ReferenceError("...");
}
deleteFirst(): SinglyLinkedList<T> {
throw new ReferenceError("...");
}
isNull(): boolean {
return true;
}
// ...
}
주의해야 할 점은 null 노드는 길이가 0인 빈 연결 리스트와는 다르다는 점입니다. 명목상 null과 동일하므로 내부에 영향을 미치는 연산은 잘못된 시도입니다. 그러나 그 외의 연산은 아무것도 하지 않을 뿐 허용됩니다. 이것이 null과 유일한 차이점입니다.
이제 기존에 작성한 모든 코드에서 null을 제거할 수 있습니다!
내용은 다음 편에서 이어집니다. 읽어주셔서 감사합니다!
묻고 답하기
개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.
![[TypeScript] 자료 구조로 담아내기. #14 - 연결 리스트(with. 이중 연결)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2FJZ8AHFr2aEg%2Fupload%2F64ada685c81df630bc522030ccb249a6.jpeg&w=3840&q=75)
![[TypeScript] 자료 구조로 담아내기. #13 - 연결 리스트(with. 탐색)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2F11KDtiUWRq4%2Fupload%2F9d73119b329ff023d19fc6162630671c.jpeg&w=3840&q=75)
![[TypeScript] 자료 구조로 담아내기. #11 - 연결 리스트(with. 헤드 노드)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2Fv8pL84kvTTc%2Fupload%2Fd70e9fdf03dc1e678f9026bee97e822d.jpeg&w=3840&q=75)
![[TypeScript] 자료 구조로 담아내기. #10 - 연결 리스트(with. 연결)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2FXe7za0JtTeM%2Fupload%2F1b7999ae5b4dd213025f4034465ddb80.jpeg&w=3840&q=75)