본문 바로가기

자료구조

이진 탐색 트리(2) - 구현

1) 이진 탐색 트리 구현

(1) 노드

- 이진 탐색 트리도 이진 트리이기 때문에,

   좌측 자식 노드와 우측 자식 노드 변수를 만들어줍니다. 

class Node{
    int key;
    Node left;
    Node right;
}

(2) 이진 탐색 트리

- 이진 탐색 트리의 기본 행위는 키를 추가하고, 삭제하고, 찾는 것입니다. 

 

(2-1) 추가

- 키를 추가하는 것은 루트가 null인 경우와 루트가 null이 아닌 경우로 나누어집니다.

  루트가 null인 경우는 새로운 노드를 루트 노드로 저장하고,

  루트가 null이 아닌 경우는 재귀적으로 insertNode 메소드를 호출하여, 

  노드가 삽입되어야 할 위치를 재귀적으로 찾아, 새로운 노드를 반환 후, 

  이전 분기점으로 돌아가 연결시키는 방식으로 동작합니다. 

 

(2-2) 가장 작은 키를 가진 노드를 찾기

- 좌측 자식이 null 값이 될 때까지 재귀적으로 호출합니다. 

  

(2-3) 가장 큰 키를 가진 노드를 찾기

- 우측 자식이 null 값이 될 때까지 재귀적으로 호출합니다. 

 

(2-4) 키를 삭제

- 키를 삭제하는 것은 크게 3가지 흐름으로 진행됩니다.

  (1) 삭제할 키를 찾아가는 행위

  (2) 삭제할 키를 찾으며, 좌측 자식에서 가장 큰 키 또는 우측 자식에서 가장 작은 키를 찾아 스왑하는 행위

  (3) 리프 노드이면 연결을 끊는 행위

 

(2-5) 키를 검색

- 재귀적으로 호출한다는 점과 반환값이 존재한다는 점 때문에 

  키의 삽입, 삭제, 검색은 비슷합니다. 

  따라서 하나를 이해하면 전반적인 원리가 이해됩니다.  

class BinarySearchTree{

   Node root;
   
   public int search(int key){
     return searchNode(root, key).key;
   }
   
   Node getSmallestNode(Node x){
      if(null == x.left){
         return x;
      }
      return getSmallestNode(x.left);
   }
   
   Node getLargestNode(Node x){
      if(null == x.right){
        return x;
      }
      return getLargetNode(x.right); 
   }
   
   Node searchNode(Node x, int key){
      Node node = x;
      if(null == node){
         throw new RuntimeException("노드가 없음");
      }else if(node.key > key){
         node = searchNode(x.left, key);
      }else if(node.key < key){
         node = searchNode(x.right, key);
      }  
      return node;
   }
   
   public void add(int key){
      Node newNode = new Node(key);
      
      if(root == null){
         root = newNode;
      }else{
         root = insertNode(root, newNode);
      }
   }
   
   
   Node insertNode(Node x, Node newNode){
       if(null == x){
          return newNode;
       }else if(x.key > newNode.key){
          x.left = insertNode(x.left, newNode);
       }else{
          x.right = insertNode(x.right, newNode);
       }
       return x;
   }


   Node removeNode(Node x, int key){
      if(null == x){
         throw new RuntimeException("노드가 존재하지 않음");
      }else if(x.key > key){
         x.left = removeNode(x.left, key);
      }else if(x.key < key){
         x.right = removeNode(x.right, key);
      }else{
        if(null != x.left){
          Node predecessor = getLargestNode(x.left);
          int removeKey = x.key;
          x.key = predecessor.key;
          predecessor.key = removeKey;
          x.left = removeNode(x.left, key);
        }else if(null != x.right){
          Node successor = getSmallestNode(x.right);
          int removeKey = x.key;
          x.key = successor.key;
          successor.key = removeKey;
          x.right = removeNode(x.right, key);
        }else{
          return null;
      }
     }
     return x;
   }



}

 

참고

코드라떼 자료구조

'자료구조' 카테고리의 다른 글

AVL 트리(2) - 구현  (0) 2022.09.19
AVL 트리(1) - 개념  (0) 2022.09.12
이진 탐색 트리(1) - 개념  (0) 2022.09.12
이진 트리  (0) 2022.09.03
트리 - 개념  (0) 2022.09.01