연결 리스트를 구현하면서 append() 메서드를 만들 때, 혼란을 겪는 지점이 있었다.
바로 tail을 수정했는데 왜 head.next가 바뀌는가?에 대한 부분이다.
class LinkedList {
constructor(value) {
this.head = { value: value, next: null };
this.tail = this.head; // 초기 상태: head와 tail이 같은 객체를 참조
this.length = 1;
}
append(value) {
const newNode = new Node(value);
this.tail.next = newNode; // [질문 포인트] 왜 head.next도 newNode가 될까?
this.tail = newNode; // tail을 새 노드로 교체
this.length++;
}
}
리스트에 데이터가 하나(length: 1)일 때 append(2)를 하면, head.next는 생성자에서 정한 대로 계속 null이어야 할 거로 생각했다. 하지만 실제로는 head.next에 자동으로 2번 노드가 연결됬다.
그 이유는 this.tail = this.head가 복사가 아닌 참조이기 때문이였다.
초기 상태: this.head와 this.tail은 메모리상의 동일한 노드 객체(A)를 가리키는 이정표가된다.
this.tail.next = newNode: tail이 가리키는 객체(A)의 next를 수정한다. 그런데 head도 객체(A)를 보고 있으므로, head.next 역시 자연스럽게 newNode를 가리키게 된다!
여기서 this.tail은 이제 객체(A)를 버리고 새 노드 객체(B)를 가리키게 된다.
하지만 this.head는 여전히 객체(A)를 잡고 있다.
결과적으로 head(A) -> B(tail) 라는 연결 구조가 완성된다.
즉, this.length = 1 일 때 append를하게되면 this.head.next와 this.tail을 동시에 수정하게되는 셈인거다.