음....안녕하세요!
처음으로 질문 글에 답해보네요 헤헤
우선 고생하셨어요~ 한달전 질문이라 다른분들 코드보면서 아셨을 수도 있는데 일단 제가 아는한 답해드릴게요
만약 left child와 right child의 위치를 고정해둔다면 (*2 +1 ,*2+2 등) 말씀하신대로 어마어마한 크기의 배열이 필요해요. 그래서 다른 방법을 쓰셔야해요
두 가지 방법을 고안했어요
참 그리고 들어오는 입력 중에 이런게 있는지 모르겠네요
아직 부모 노드의 위치를 모르는데 자식 노드의 위치를 주어지는 경우
예)
6
A B C
D E F
B D .
C . .
E . .
F . .
저는 둘 다 이런 케이스도 풀 수 있도록 짰어요
첫번째 방법은 이게 대문자 알파벳으로만 들어온다는 점을 중요하게 생각한 방법이고요(소스코드 올려두었어요)
26개의 배열을 선언하여 순서대로 A ... Z까지 의미하고 걔네들의 자식노드의 위치를 저장해요
그리고 주어진 노드가 맞는지(isused) 체크해서 주어진 노드가 아니면 무시하고요...
이 방법의 장점은 위치를 찾을 필요가 없어요
앞서 말한 아직 부모 노드의 위치를 모르는데 자식 노드의 위치를 주어지는 경우를 대비하기 위해
입력을 전부 받아두고 자식 노드의 위치를 찾아야하지만 이 방법은 그럴 필요가 없어요
입력 받는 순서대로 저장하면 되요
그런데 이런 방법은 알파벳이나 숫자(0~9)같은 몇몇 케이스에만 적용할 수 있어요. 그래서 다른 방법을 소개시켜드릴게요
배열을 선언해서 순서대로 넣는거에요
방법은 간단하지만 이 방법은 자식 노드의 위치를 찾아서 저장하는 걸 한번 하기 때문에 그렇게 효율적이진 않아요 사실 이게 26개까지만 들어와서 괜찮지 더 많이 들어오면 O(n^2)애여서 좀 힘들어요
시간 복잡도를 줄이려면 arr을 sort해서 binary search하시면 O(nlogn)까지 줄일 순 있긴해요
그리고 개행문자나 space 문자 안받으시려면 scanf(" %c",&c);처럼 %c앞을 한칸 띄우시면 공백문자는 무시하고 받으라는 뜻이되요
또 for문안에 i가 0일때 따로 처리하셨는데 이러면 for문 돌면서 계속 if확인하니까 0인경우를 for문 앞에 써주시고 for문을 1부터 시작하시면 더 좋아요
마지막으로 재귀함수를 좀 복잡하게짜셨는데....함수가 종료되면 함수가 불려졌던 곳에서 부터 다시 실행되요 그런데 지금 이 코드는 index를 계속 바꾸면서 호출하게해서 호출자체가 많은데 지금은 상관없는데 다른 문제같은경우는 이렇게 짜시면 스택이 터질수도 있을거같아요....
jeul2 6년 전
트리를 처음 접해서 짜본 문제입니다.
연결리스트로 해보려다 트리를 입력받는게 생각보다 어려워 먼저 배열로 짜게 되었는데요.
이진트리의 최악의 경우는 일자형태인 변질트리(Degenerate Tree)라고 들었습니다.
노드개수3
A . B
B . C
C . .
노드의 개수를 받는다면 일자형태가 된다하면 레벨이 노드개수만큼 깊에 들어가게되고 이에따라 배열크기가 늘어날거라 생각해서
N<=26이므로 배열을 0부터 알차게 사용한다면 (2^26 - 1)크기의 배열이 필요할 것 같았는데 막상 해보니깐 런타임에러가 떠서
좋지못한 방법이지만 어찌어찌 정답은 맞추게 되었습니다..
아마 테스트케이스가 없는 이유는 문제와 맞지 않아서?
일자가 되는 경우는 이 문제에서 원하는 것도 아니고, 트리를 쓰는 이유도 사라지지만 제가 생각한 배열크기가 혹시 잘못되었나 해서 궁금해서 질문남깁니다.
추가로 if문 4개로 리커시브를 만들었는데 비효율적인것같다는 생각이 듭니다. 비효율적인가요?
아래 소스코드 남기고 간단히 주석달아놓았습니다.