๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜/์ž๋ฃŒ๊ตฌ์กฐ

[Java] Binary Search Tree

by ๐Ÿณ Laboon 2024. 7. 8.

์•ž ํฌ์ŠคํŒ…์—์„œ ์ž‘์„ฑํ•œ Tree์˜ ๋น„ํšจ์œจ์ ์ธ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ๊ธด ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋‹ค.

ํŠธ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ์ž์‹์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ์—์„œ๋Š” Binary Tree์˜ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—

์ž์‹์ด Left, Right๋งŒ ์กด์žฌํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Log_2 (N) ๋ฒˆ๋งŒ์— ๋ชจ๋“  ์ˆ˜ํ–‰์„ ๋๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

๋˜, inorder๋ฅผ ์ˆ˜ํ–‰ ์‹œ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ๋œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

package com.study.datastructrue.nonlinear.binarysearchtree;

public class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
       this.value = value;
       left = null;
       right = null;
    }
}

 

๊ธฐ๋ณธ ์ ์ธ ๋…ธ๋“œ ์ •๋ณด์ด๋‹ค.

 

package com.study.datastructrue.nonlinear.binarysearchtree;

public class LinkedListBST {
    private Node root;
    private int size;

    public LinkedListBST() {
       this.root = null;
       this.size = 0;
    }

    public void add(int value) {
       this.root = addRecursive(root, value);
       this.size++;
    }

    private Node addRecursive(Node current, int value) {
       if (current == null) {
          return new Node(value);
       }

       if (value < current.value) {
          current.left = addRecursive(current.left, value);
       } else if (value > current.value) {
          current.right = addRecursive(current.right, value);
       }

       return current;
    }

    public boolean delete(int value) {
       int originalSize = size;
       this.root = deleteRecursive(root, value);
       return size < originalSize;
    }

    private Node deleteRecursive(Node current, int value) {
       if (current == null) {
          return null;
       }

       if (value == current.value) {
          if (current.left == null && current.right == null) {
             size--;
             return null;
          }

          if (current.left == null) {
             size--;
             return current.right;
          }

          if (current.right == null) {
             size--;
             return current.left;
          }

          int smallestValue = findSmallestValue(current.right);
          current.value = smallestValue;
          current.right = deleteRecursive(current.right, smallestValue);
          return current;
       }

       if (value < current.value) {
          current.left = deleteRecursive(current.left, value);
          return current;
       }

       current.right = deleteRecursive(current.right, value);
       return current;
    }

    private int findSmallestValue(Node root) {
       return root.left == null ? root.value : findSmallestValue(root.left);
    }

    public void printTree() {
       printTree(root, 0);
    }

    private void printTree(Node node, int level) {
       if (node == null) {
          return;
       }

       printTree(node.right, level + 1);

       if (level != 0) {
          for (int i = 0; i < level - 1; i++) {
             System.out.print("|\t");
          }
          System.out.println("|-------" + node.value);
       } else {
          System.out.println(node.value);
       }

       printTree(node.left, level + 1);
    }

    public void traverseInOrder() {
       traverseInOrder(root);
       System.out.println();
    }

    private void traverseInOrder(Node node) {
       if (node != null) {
          traverseInOrder(node.left);
          System.out.print(" " + node.value);
          traverseInOrder(node.right);
       }
    }

    public void traversePreOrder() {
       traversePreOrder(root);
       System.out.println();
    }
    private void traversePreOrder(Node node) {
       if (node != null) {
          System.out.print(" " + node.value);
          traversePreOrder(node.left);
          traversePreOrder(node.right);
       }
    }
    public void traversePostOrder() {
       traversePostOrder(root);
       System.out.println();
    }
    private void traversePostOrder(Node node) {
       if (node != null) {
          traversePostOrder(node.left);
          traversePostOrder(node.right);
          System.out.print(" " + node.value);
       }
    }

    public int size() {
       return size;
    }

}

 

1. ์ž‘์€ ๊ฐ’์€ ์™ผ์ชฝ ์ž์‹์œผ๋กœ ํฐ ๊ฐ’์€ ์˜ค๋ฅธ์ชฝ ์ž์‹์œผ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค.

( ์ค‘๋ณต๋œ ๊ฐ’์„ ํ—ˆ์šฉํ•  ๊ฒฝ์šฐ, count๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.)

2. ์‚ญ์ œ ์‹œ ๊ณ ๋ คํ•  ์ ์ด ์žˆ๋‹ค.

- ์‚ญ์ œํ•  ๊ฐ’์„ ์ฐพ์•˜์„ ๊ฒฝ์šฐ, 

1) ์ž์‹์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‚ด๊ฐ€ ์ง€์›Œ์ง„ ๊ฒƒ์ด๋‹ˆ null์„ ๋ฐ˜ํ™˜

2) ์™ผ์ชฝ ์ž์‹์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์˜ค๋ฅธ์ชฝ ์ž์‹์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์„œ Level์„ ๋งž์ถค.

3) ์˜ค๋ฅธ์ชฝ ์ž์‹์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์™ผ์ชฝ ์ž์‹์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์„œ Level์„ ๋งž์ถค.

4) ์ž์‹์ด ๋‘˜ ๋‹ค ์กด์žฌํ•œ๋‹ค๋ฉด ํฐ ๋…€์„ ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๋…€์„์œผ๋กœ ๊ต์ฒดํ•ด์ฃผ์–ด์•ผ ํ•จ. inorder์˜ ํŠน์„ฑ์„ ๋งž์ถ”๊ธฐ ์œ„ํ•จ.

 

TreePrint ๋ฐ PreOrder, InOrder, PostOrder ๊ฒฐ๊ณผ

4๋ฅผ ์ง€์šด ํ›„์—๋„ InOrder ๊ฒฐ๊ณผ๊ฐ€ ์˜ค๋ฆ„์ฐจ์ˆœ ์ธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ.

 

package com.study.datastructrue.nonlinear.binarysearchtree;

public class ArrayBST {
    private int[] tree;
    private int size;

    public ArrayBST(int capacity) {
       tree = new int[capacity];
       size = 0;

       for (int i = 0; i < capacity; i++) {
          tree[i] = Integer.MIN_VALUE;
       }
    }

    public void add(int value) {
       if (size == 0) {
          tree[0] = value;
          size++;
       } else {
          addRecursive(0, value);
       }
    }

    private void addRecursive(int index, int value) {
       if (tree[index] == Integer.MIN_VALUE) {
          tree[index] = value;
          size++;
       } else if (value < tree[index]) {
          int leftChildIndex = 2 * index + 1;
          addRecursive(leftChildIndex, value);
       } else if (value > tree[index]) {
          int rightChildIndex = 2 * index + 2;
          addRecursive(rightChildIndex, value);
       }
    }
    public void printTree() {
       printTreeRecursive(0, 0);
    }

    private void printTreeRecursive(int index, int level) {
       if (index >= tree.length || tree[index] == Integer.MIN_VALUE) {
          return;
       }
       printTreeRecursive(2 * index + 2, level + 1);

       for (int i = 0; i < level; i++) {
          System.out.print("    ");
       }
       System.out.println(tree[index]);

       printTreeRecursive(2 * index + 1, level + 1);
    }

}

 

BST๋Š” LinkedList ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Array๋กœ๋„ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Array BST ์‹คํ–‰๊ฒฐ๊ณผ

 

package com.study.datastructrue.nonlinear.binarysearchtree;

import java.util.TreeSet;

public class Main {

    public static void main(String[] args) {
       LinkedListBST bt = new LinkedListBST();

       bt.add(6);
       bt.add(4);
       bt.add(8);
       bt.add(3);
       bt.add(5);
       bt.add(7);
       bt.add(9);

       bt.printTree();
       bt.traversePreOrder();
       bt.traverseInOrder();
       bt.traversePostOrder();

       bt.delete(4);
       bt.printTree();
       bt.traverseInOrder();

       ArrayBST bst = new ArrayBST(10);
       bst.add(6);
       bst.add(4);
       bst.add(8);
       bst.add(3);
       bst.add(5);
       bst.add(7);
       bst.add(9);
       bst.printTree();
    }

}

 

Java์—์„œ๋Š” Tree๋ฅผ ๊ตฌํ˜„ํ•ด ๋‘” ๊ฒƒ์ด ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ TreeSet ๊ณผ TreeMap ์ด๋‹ค. 

ํ•˜์ง€๋งŒ Java์˜ Tree๋Š” Red-Black Tree๋กœ ์ž๊ฐ€๊ท ํ˜•ํŠธ๋ฆฌ๋ผ๊ณ ๋„ ํ•œ๋‹ค.

์ด๊ฒƒ์€ ์ด์ง„ ํŠธ๋ฆฌ ์ข…๋ฅ˜ ์ค‘ ๊ท ํ˜•ํŠธ๋ฆฌ๋ผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘ ํ•˜๋‚˜์ธ๋ฐ ๋‹ค์Œ ํฌ์ŠคํŠธ์— ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.