본문 바로가기
그룹 스터디 공부(알고리즘)/백준(알고리즘)

[JAVA] 백준 1991 번 트리 순회

by hanyugyeong 2023. 8. 4.
반응형
SMALL

JAVA 백준 1991번 트리 순회

트리 순회 문제 링크

 

1991번: 트리 순회

첫째 줄에는 이진 트리의 노드의 개수 N(1 ≤ N ≤ 26)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 노드와 그의 왼쪽 자식 노드, 오른쪽 자식 노드가 주어진다. 노드의 이름은 A부터 차례대로 알파

www.acmicpc.net

이진 트리를 입력받아 전위 순회(preorder traversal), 중위 순회(inorder traversal), 후위 순회(postorder traversal)한 결과를 출력하는 프로그램을 작성하시오.

예를 들어 위와 같은 이진 트리가 입력되면,

  • 전위 순회한 결과 : ABDCEFG // (루트) (왼쪽 자식) (오른쪽 자식)
  • 중위 순회한 결과 : DBAECFG // (왼쪽 자식) (루트) (오른쪽 자식)
  • 후위 순회한 결과 : DBEGFCA // (왼쪽 자식) (오른쪽 자식) (루트)

가 된다

입력

첫째 줄에는 이진 트리의 노드의 개수 N(1 ≤ N ≤ 26)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 노드와 그의 왼쪽 자식 노드, 오른쪽 자식 노드가 주어진다. 노드의 이름은 A부터 차례대로 알파벳 대문자로 매겨지며, 항상 A가 루트 노드가 된다. 자식 노드가 없는 경우에는 .으로 표현한다.

7
A B C
B D .
C E F
E . .
F . G
D . .
G . .


출력

첫째 줄에 전위 순회, 둘째 줄에 중위 순회, 셋째 줄에 후위 순회한 결과를 출력한다. 각 줄에 N개의 알파벳을 공백 없이 출력하면 된다.

ABDCEFG
DBAECFG
DBEGFCA

 

풀이 (깃허브)

해당 문제는 재귀함수에 대한 이해가 필요하다 

tree 자료구조를 이용해서 풀었습니다

https://github.com/funhappyit/Algorithm/tree/main/%EB%B0%B1%EC%A4%80/Silver/1991.%E2%80%85%ED%8A%B8%EB%A6%AC%E2%80%85%EC%88%9C%ED%9A%8C

 

접근 방식 

주어진 대로 트리를 생성한다. 전위, 중위, 후위 순회를 재귀를 이용하여 출력한다.

1.트리의 기초인 노드 클래스를 먼저 생성한다.

2.트리 클래스를 만든다. 트리 클래스는 아래의 매서드들로 구성된다

 1) 값을 추가하는 add() 메서드

 2) 어느 위치에 추가할 것인지 위치를 찾아주는 search() 메서드

 3) 전위순회(preorder), 중위순회(inorder), 후위순회(postorder) 메서드

 

노드 클래스를 생성하면 아래와 같다. 이 문제에서 트리는 이진트리이므로 노드는 left,right로 구성된다

 

class Node{
	char Data;
	Node Left, Right;
	public Node(char Data){
		this.Data = Data;
	}
}// class Node

트리 클래스의 구성

class Tree{
    Node root; //루트 노드. 처음엔 null 상태이다.
    public void add(char data, char leftData, char rightData){
        //추후 구현
    }
    private void search(Node root, char data, char leftData, char rightData){
        //추후 구현
    }
    public void preorder(Node root){
        //추후 구현
    }
    public void inorder(Node root){
        //추후 구현
    }
    public void postorder(Node root){
        //추후 구현
    }
}

전체 소스

import java.io.IOException;
import java.util.Scanner;

class Node{
	char Data;
	Node Left, Right;
	public Node(char Data){
		this.Data = Data;
	}
}// class Node

class Tree{
	Node Root;
	public void Add(char Data, char Left_Data, char Right_Data){
		if(Root==null){
			//Data가 .이 아니라면 루트에 Data 값을 가진 노드 생성
			if(Data!='.') Root = new Node(Data);
			//왼쪽 자식 노드 데이터가 .이 아니라면 Left_Data를 가진 왼쪽 자식 노드 생성
			if(Left_Data != '.')Root.Left = new Node(Left_Data);
			//오른쪽 자식 노드 데이터가 .이 아니라면 Right_Data를 가진 오른쪽 자식 노드 생성
			if(Right_Data != '.') Root.Right = new Node(Right_Data);
		}else{
			//루트가 널이 아니라면 탐색
			Search(Root,Data,Left_Data,Right_Data);
		}
	}
	public void Search(Node Root,char Data, char Left_Data, char Right_Data){
		//만약에 루트노드가 null이면 종료
		if(Root ==null) return;
		//루트 노드의 데이터가 Data라면
		else if(Root.Data == Data){
			if(Left_Data != '.') Root.Left = new Node(Left_Data);
			if(Right_Data != '.') Root.Right = new Node(Right_Data);
		//아니라면 못 찾았다면
		}else{
			Search(Root.Left, Data,Left_Data,Right_Data);
			Search(Root.Right,Data,Left_Data,Right_Data);
		}
	}

	public void PreOrder(Node Root){
		//루트 -> 왼쪽 자식 -> 오른쪽 자식
		//먼저 루트노드 출력
		System.out.print(Root.Data);

		if(Root.Left != null) PreOrder(Root.Left);
		if(Root.Right != null) PreOrder(Root.Right);
	}

	public void InOrder(Node Root){
		// 왼쪽 자식->루트->오른쪽 자식
		if(Root.Left!=null) InOrder(Root.Left);
		//루트노드 출력
		System.out.print(Root.Data);
		if(Root.Right != null) InOrder(Root.Right);

	}
	public void PostOrder(Node Root){
		// 왼쪽 자식->루트->오른쪽 자식
		if(Root.Left!=null) PostOrder(Root.Left);
		if(Root.Right != null) PostOrder(Root.Right);
		//루트노드 출력
		System.out.print(Root.Data);


	}



}
public class Main {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt(); // 트리노드의 개수

		Tree tree = new Tree();
		for(int i=0;i<N;i++){
			tree.Add(sc.next().charAt(0),sc.next().charAt(0),sc.next().charAt(0));
		}
		tree.PreOrder(tree.Root);
		System.out.println();
		tree.InOrder(tree.Root);
		System.out.println();
		tree.PostOrder(tree.Root);

	}


}
반응형
LIST