Rose tree는 임의의 갯수의 자식 노드를 가질 수 있는 트리 구조임.
<각 노드에 정수를 저장한 rose tree의 예시>
자식 노드가 0개라면 leaf가 되는거고, 1개 이상이라면 internal node가 되는셈.
Rose tree는 하스켈과 러스트에서 각각 아래와 같이 정의할 수 있음
이제 이 트리의 순회를 생각해보자. rose tree의 원소들을 preorder로 순회하여 리스트로 만드는 함수는 다음과 같이 구현할 수 있음.
toList :: Tree a -> [a] toList (Node x ts) = x : (ts >>= toList)혹은
toList :: Tree a -> [a] toList (Node x ts) = x : concatMap toList ts여기서 concatMap은 flatMap이라고도 불리는 함수이고, 다음과 같이 정의됨
concat :: [[a]] -> [a] map :: (a -> b) -> [a] -> [b] concatMap :: (a -> [b]) -> [a] -> [b] concatMap f xs = concat (map f xs)이제 테스트를 해보면
t1 :: Tree Int t1 = Node 1 [ Node 2 [ Node 3 [ Node 4 [] , Node 5 [] ] , Node 6 [] ] , Node 7 [ Node 8 [] , Node 9 [] ] , Node 10 [ Node 11 [ Node 12 [] ] , Node 13 [ Node 14 [] ] , Node 15 [] ] ] >> toList t1 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]리스트가 잘 나옴.
보면 알겠지만, 재귀 호출과 고차함수를 활용하면 toList를 아주 쉽게 구현할 수 있음.
하지만 이번 문제는 재귀와 고차함수를 사용하지 않고 트리 순회함수 toList를 구현하는 것임.
단, 함수형 언어의 경우 재귀를 전혀 사용하지 않고서는 프로그래밍이 불가능 하므로 꼬리재귀는 허용함.
스택을 사용해서 재귀호출 없이 이진트리를 순회하는 알고리즘이 있으니 이걸 변형하거나
재귀 알고리즘을 먼저 짠 다음에 루프로 변환하면 됨.
#### 추가문제 ####
toList는 너무 쉽게 풀려서 추가문제를 내겠음.
fold 함수를 꼬리재귀 혹은 루프를 사용해서 구현하기.
참고로 fold로 toList를 구현할 수 있음
나는 fold에서 쓸 수 있는 방식으로 toList 구현하고서 문제로 낸건데, toList에서만 되는 더 쉬운 방법을 미처 생각을 못했음.
스택쓸래
섹스도 못하는게 찐따같이 문제는 쳐내고잇네
그래서 게이는 섹스 해봤노?
상금은 무엇?
센세, 로즈트리의 자식노드는 크든 작든 상관없습니까?
키가
BST도 balanced도 아니기 때문에 다른 조건은 업슴미다
해당 댓글은 삭제되었습니다.
그게 아마 DAG는 non-well-founded 인 경우일 거고 이 문제는 well founded rose tree 라서 그냥 rooted tree로 이해해도 됨
근데 지금 문제를 잘못내서 너무 쉽게 풀려서 추가문제 낼 예정임
fold함수는 무슨 일을 합니까?
fold 함수는 인자로 받은 Tree a 를 '접어서' 출력 b를 만드는데, 트리를 어떻게 접을지에 대한 규칙을 인자 f : a -> [b] -> b 로 받음
그래서 fold는 인자로 받은 함수 f가 무엇이냐에 따라서 다른 일을 하는데, f = λ x ys -> x : concat ys 를 규칙으로 준다면 toList와 같은 일을 하는 함수가 되는거임
사실 내가 문제로 내기에 적당한 함수를 못찾아서 fold를 가져온건데, 문제 주제랑 상관 없는 이유로 어려운것 같아서 더 괜찮은 함수가 있나 찾아보겠음
제가 바보라서 저런 정의 언어를 못 보내요.
https://gall.dcinside.com/mgallery/board/view/?id=github&no=31236&page=1
조금 더 이해하기 쉬운 함수로 가져와봤음
문제 수정본
https://gall.dcinside.com/mgallery/board/view/?id=github&no=31236&page=1