트리를 이용해 직접 구현하는 경우는 거의 없지만 관련 라이브러리나 문서를 이해할 때 좋다
계층적 데이터의 집합
루트 노드
는 하나만 존재한다.
8. 자녀 노드는 하나의 부모 노드만 존재
노드
의 깊이(Depth) 트리
의 깊이(depth)노드
의 높이(height) : 문서마다 높이를 간선으로 따지기도 하고 노드 수로 따지기도 트리
의 높이노드
의 크기(size)트리
의 크기(size)계층 구조를 나타내거나 데이터를 조직화하여 사용되는 중요한 자료구조
없거나 두 개
인 트리 = 자녀 노드가 1개인 노드는 없다.왼쪽
자녀 노드만 가지는 트리쪽
자녀 노드만 가지는 트리내부 노드
: 루트 노드와 리프 노드(leaf node)를 제외한 나머지 노드를 의미preorder.stream().mapToInt(Integer::intValue).toArray()
preorder
리스트를 스트림으로 변환하고, 각 요소를 mapToInt()
메서드를 이용해 int
형으로 변환Integer::intValue
는 Integer 클래스의 intValue 메서드를 호출하여 int로 변환하는 것을 의미toArray()
메서드를 사용하여 해당 스트림의 요소들을 배열로 변환import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
//이진 트리 노드(value : 노드 숫자 x,y : 노드 위치 - 좌표 )
// left, right : 각각 왼쪽 자식인지 오른쪽 자식인지 구분
private static class Node{
public final int value;
public final int x;
public final int y;
public Node left;
public Node right;
private Node(int value, int x, int y){
this.value = value;
this.x = x;
this.y = y;
}
}
// 노드를 삽입하는 메서드, 주어진 노드를 현재 노드의 왼쪽 또는 오른쪽에 삽입
// 위치 좌표를 기준으로 비교하여 적절한 위치에 노드를 삽입
private void insert(Node root, Node node){
if(node.x < root.x) {
if (root.left == null) {
root.left = node;
} else {
insert(root.left, node);
}
}
else{
if(root.right == null){
root.right = node;
}
else{
insert(root, node);
}
}
}
//노드 배열을 받아 이진 트리를 생성하는 메서드
// 배열의 첫 번째 노드를 루트로 지정하고, 나머지 노드들을 insert 메서드를 통해 적절한 위치에 삽입하여 전체 트리를 구성
private Node constructTree(Node[] nodes){
Node root = nodes[0];
for(int i = 1; i<nodes.length; i++){
insert(root, nodes[i]);
}
return root;}
// 전위 순회
// 노드를 방문하면서 노드의 값을 리스트에 추가한 후, 왼쪽 자식 노드를 재귀적으로 순회하고 오른쪽 자식 노드를 재귀적으로 순회
private void pre(Node node, List<Integer> visits){
if(node == null) return;
visits.add(node.value); // 현재 노드 값을 방문 리스트에 추가
pre(node.left, visits); // 왼쪽 자식 노드를 전위 순회
pre(node.right, visits); // 오른쪽 자식 노드를 전위 순회
}
// 후위 순회
// 노드의 왼쪽 자식 노드와 오른쪽 자식 노드를 재귀적으로 순회한 후, 현재 노드의 값을 리스트에 추가
private void post(Node node, List<Integer> visits){
if(node == null) return;
// 끝부터 후
post(node.left, visits);
post(node.right, visits);
// 마지막에 넣어줌
visits.add(node.value);
}
public int[][] solution(int[][] nodeinfo)
{
Node[] nodes = new Node[nodeinfo.length];
for (int i = 0; i < nodes.length; i++)
{
// 각 인덱스에 노드 정보 저장, i + 1은 노드의 값을 의미하며, nodeinfo[i][0]은 x 좌표, nodeinfo[i][1]은 y 좌표를 나타낸다
nodes[i] = new Node(i + 1, nodeinfo[i][0], nodeinfo[i][1]);
}
Arrays.sort(nodes, (a, b) -> b.y - a.y); // 윗부분부터 순회하기 위해서 y좌표를 내림차순으로 정렬
// 노드 정보들이 정렬되었으므로, 배열의 첫 노드부터 순회하며 트리를 구성한다.
Node root = constructTree(nodes); // 이진 트리 생성
List<Integer> preorder = new ArrayList<>();
pre(root,preorder);
List<Integer> postorder = new ArrayList<>();
post(root,preorder);
// preorder와 postorder 리스트의 요소들을 각각 int 배열로 변환하여 최종적인 결과를 반환
return new int[][] {
preorder.stream().mapToInt(Integer::intValue).toArray(),
postorder.stream().mapToInt(Integer::intValue).toArray(),
};
}
}
탐색
이 동작할 수 있도록 고안된 효율적인 탐색이 가능한 자료구조의 일종// 전위 순회
private void pre(Node node, List<Integer> visits){
if(node == null) return;
visits.add(node.value);
pre(node.left, visits);
pre(node.right, visits);
}
⇒ 작은값 기준으로 순서대로 방문
재귀적으로 왼쪽 서브 트리 순회 ⇒ 현재 노드 방문(값 출력) ⇒ 재귀적으로 오른쪽 서브 트리 순회
// 후위 순회
private void post(Node node, List<Integer> visits){
if(node == null) return;
// 끝부터 후
post(node.left, visits);
post(node.right, visits);
// 마지막에 넣어줌
visits.add(node.value);
}
검색
없는
노드 삭제(delete)null
하나
인 노드 삭제(delete)둘
인 노드 삭제(delete)이진 탐색 트리가 이미 구성되어 있다고 가정, 찾고자 하는 원소 : 37
출처 : http://yahma.tistory.com/85