-
Common Lisp으로 구현한 트리(Tree)를 중위 순회(In-order Traversal)하는 반복자(Iterator)Programmer/Programming 2016. 5. 17. 15:02
사소해 보이는 연산 뒤에 숨어있는 것 은 인턴 전화 면접에서 깨달은 내용을 담고 있다.
이 글은 인턴 면접을 소재로 하는데,
면접의 내용 중에 트리(Tree)를 중위 순회(Inorder Traversal)하는 반복자를 구현하는 것이 있다.
이 글의 필자는 C++로 구현하였다. 1평소 업무에서 Common Lisp을 쓸 기회가 없어서 자꾸 잊어버린다.
도구를 갈고 닦지 않으면 녹슬기 마련이다.
간단하게 트리의 중위 순회를 Common Lisp으로 작성해봤다.순회 순서
- 왼쪽의 하위 트리를 순회한다.
- 자신(중간)
- 오른쪽의 하위 트리를 순회한다.
순회할 첫번째 노드 구하기 : begin
- 최상위 노드의 가장 왼쪽에 있는 노드가 첫번째 노드이다.
구현은 왼쪽 하위 노드를 재귀적으로 찾는다.
(defun begin (node) (if left-node (begin left-node) node))
다음 방문할 노드 얻기 : next
- 순회 순서에 의해서 자신 이후에는 오른쪽 하위 트리를 순회한다.
따라서, 다음 노드는 오른쪽 하위 트리의 가장 왼쪽의 노드이다.(begin (right node))
- 오른쪽 하위 트리가 없다면, 이 단계에서는 더 이상 방문할 곳이 없다.
가장 가까운 상위 단계의 중간 노드를 찾는다. 2(mid node)
(defun next (node) (if right-node (begin right-node) (mid node)))
가장 가까운 상위 단계의 중간 노드 찾기 : mid
- 오른쪽(순서 3)에서 올라왔다면, 이 단계에서는 더 이상 방문할 곳이 없다.
(if (eq node (right parent-node)) ;; ... )
다시, 가장 가까운 상위 단계의 중간 노드를 찾는다.(mid mid-node)
- 아니라면, 왼쪽(순서 1)에서 올라왔다.
순회 순서에 따라서 중간 노드를 반환한다.mid-node
(defun mid (node) (when mid-node (if (eq node (right mid-node)) (mid mid-node) mid-node)))
최종 코드
(defun begin (node) (let ((left-node (left node))) (if left-node (begin left-node) node))) (defun next (node) (when node (labels ((mid (node) (let ((mid-node (parent node))) (when mid-node (if (eq node (right mid-node)) (mid mid-node) ; traversal is done for the current tree. go up the parent node mid-node))))) (let ((right-node (right node))) (if right-node (begin right-node) (mid node))))))
2016/01/13 - [Practice/Lisp] - 암호 문자열 감추기 문제 풀이 : Common Lisp, Scheme
2013/08/20 - [Theory/Data Structure] - GLib의 GTree로 알아보는 균형 이진 트리 알고리즘
'Programmer > Programming' 카테고리의 다른 글
교착상태(deadlock)를 프로세스 상태와 디버거를 사용해서 찾아내기 (1) 2017.01.06 버젼 관리 시스템을 사용하여 문제를 해결하기 (0) 2017.01.06 Lisp에서 클로저(closures) (0) 2016.02.18 Lisp에서 lexical과 dynamic 변수 타입 (0) 2016.02.18 Lisp 비교 : 암호 문자열 감추기 문제 풀이 (1) 2016.01.13 댓글