[자료구조] 이진탐색트리

최근 이진탐색트리(BST)에 관련된 내용을 질문 받았다가 내용을 제대로 숙지하지 못하고 있어 답변을 잘해내지 못했던 경험이 있다. 해당 경험을 다시 하지 않기 위해 BST에 대해서 정리해보고 나아가 업그레이드 버전인 레드 블랙 트리까지 알아보도록 하자.

이진탐색트리란?

이진탐색트리는 왼쪽 서브 트리의 모든 항목은 루트 노드의 데이터보다 작아야하고 오른쪽 서브 트리의 모든 항목은 루트 노드의 데이터보다 커야 한다는 조건을 만족한 이진 트리이다. 이름에서 알 수 있듯이 이 트리의 주 용도는 검색이다. 어떤 노드가 가질 수 있는 데이터의 종류에 대하여 제한을 두기 때문에, 검색 연산의 최악의 경우 복잡도가 O(logn)이 된다.

이진탐색트리의 주요 연산은 다음과 같다.

주요 사항은 다음과 같다.

탐색

왼쪽이나 오른쪽으로 탐색 진행하면서 찾는 노드의 값 있으면 리턴, 없으면 null 리턴

    // 재귀 시간복잡도: 최악의 경우 (BST가 경사 트리일 때) O(n), 공간복잡도: 재귀적 스택 때문에 O(n)
    // 트리가 균형 잡힌 경우 O(logn), 보통 트리 높이에 비례

    Node find(Node root, int data){
    	if(root == null) return null;
    	if(data < root.getData())
    		return find(root.getLeft(), data);
    	else
    		return find(root.getRight(), data);
    	return root;
    }

    // 비재귀 시간복잡도: O(n), 공간복잡도: O(1)
    Node find(Node root, int data){
    	if(root == null) return null;
    	while(root){
    		if(data == root.getData())
    			return root;
    		else if(data > root.getData())
    			root = root.getRight();
    		else root.getLeft();
    	}
    	return null;
    }

삽입

이진탐색트리에 데이터를 삽입하려면 먼저 이 항목의 위치를 찾아야 한다. 위치를 찾는 동안 데이터가 이미 존재한다면 무시하고 나오면 된다. 그렇지 않으면, 탐색한 경로의 마지막 위치에 데이터를 추가한다.

    // 시간복잡도: O(n), 공간복잡도: O(n), 반복적 방법은 O(1)
    Node insert(Node root, int data){
    	if(root == null){
    		root = new Node();
    		if(root == null) {
    			System.out.println("Memory Error"); return;
    		} else {
    			root.setData(data);
    			root.setLeft(null);
    			root.setRight(null);
    		}
    	} else {
    		if(data < root.getData())
    			root.setLeft(insert(root.getLeft(), data));
    		else if(data > root.getData())
    			root.setRight(insert(root.getRight(), data));
    	}
    	return root;
    }

삭제

삭제 연산은 다른 연산에 비해 약간 더 복잡하다. 삭제되는 항목이 잎 노드가 아닐 수도 있기 때문이다. 이 연산에서 역시 먼저 삭제하기 원하는 항목의 위치를 찾아야한다.

경우의 수

다양한 예제로 학습하는 데이터구조와 알고리즘 for Java, 나라심하 카루만치

더 알아볼 것