‡πŸ‘©‍πŸ’» ‡/º Java

[자료ꡬ쑰] 이진 탐색 트리 κ΅¬ν˜„ | Java

Trudy | 솑연 2023. 12. 9. 18:11

πŸ“μ΄μ§„ 탐색 νŠΈλ¦¬λž€?

이진 트리의 속성은 λ‹€μŒκ³Ό κ°™λ‹€. 

 

1. μ€‘λ³΅λœ λ…Έλ“œκ°€ μ—†μ–΄μ•Όν•œλ‹€. 

2. λͺ¨λ“  λ…Έλ“œμ˜ μ™Όμͺ½ μ„œλΈŒ νŠΈλ¦¬μ—λŠ” ν•΄λ‹Ή λ…Έλ“œλ³΄λ‹€ μž‘μ€ 값을 μ§€λ‹Œ λ…Έλ“œλ“€λ‘œ 이루어져 μžˆλ‹€. 

3. λͺ¨λ“  λ…Έλ“œμ˜ 였λ₯Έμͺ½ μ„œλΈŒ νŠΈλ¦¬μ—λŠ” ν•΄λ‹Ή λ…Έλ“œλ³΄λ‹€ 큰 값을 μ§€λ‹Œ λ…Έλ“œλ“€λ‘œ 이루어져 μžˆλ‹€. 

4. μ€‘λ³΅λœ λ…Έλ“œκ°€ μ—†μ–΄μ•Όν•œλ‹€. 

5. μ™Όμͺ½ μ„œλΈŒνŠΈλ¦¬μ™€ 였λ₯Έμͺ½ μ„œλΈŒνŠΈλ¦¬ λ˜ν•œ μ΄μ§„νƒμƒ‰νŠΈλ¦¬μ΄λ‹€. 

 

μ΄μ§„νƒμƒ‰νŠΈλ¦¬μ˜ 단점

μ΄μ§„νƒμƒ‰νŠΈλ¦¬μ˜ μ‚½μž…κ³Ό μ‚­μ œ 연산은 탐색이후 이루어지기 λ•Œλ¬Έμ—

탐색에 ν•„μš”ν•œ O(h)이 μ†Œμš”λ˜λ©° μ—°κ²°λ¦¬μŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ μž…λ ₯κ³Ό μ‚­μ œμ—λŠ” O(1)이 μ‚¬μš©λœλ‹€.

λ”°λΌμ„œ 총 μ†Œμš”λ˜λŠ” μ‹œκ°„ λ³΅μž‘λ„λŠ” O(h)이며 μ΅œμ•…μ˜ 경우 탐색과 λ™μΌν•˜κ²Œ O(N)이 μ†Œμš”λœλ‹€.

λ‹€μŒκ³Ό 같이 이진 탐색 νŠΈλ¦¬λŠ” ν•œμͺ½ λ°©ν–₯으둜 λ…Έλ“œκ°€ μ§‘μ€‘λœ 편ν–₯νŠΈλ¦¬μ—μ„œλŠ” νš¨μœ¨μ μ΄μ§€ μ•Šλ‹€.

 

μ΄λŸ¬ν•œ 단점을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ Balance Treeλ₯Ό μ΄μš©ν•˜λŠ”λ°, B-Tree, AVL, Red-Black Tree 등이 μžˆλ‹€.

 

 

Binary Search Tree visualization

https://www.cs.usfca.edu/~galles/visualization/BST.html

 

μ°Έκ³ 

https://ratsgo.github.io/data%20structure&algorithm/2017/10/22/bst/


πŸ“μ½”λ“œ 

 

Node.java

package tree;

public class Node implements TreePrinter.PrintableNode{
    Integer data;
    Node left;
    Node right;

    @Override
    public TreePrinter.PrintableNode getLeft() {
        return this.left;
    }

    @Override
    public TreePrinter.PrintableNode getRight() {
        return this.right;
    }

    @Override
    public String getText() {
        return "["+data+"]";
    }

    public Node(Integer data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

 

BinarySearchTree.java

package tree;

public class BinarySearchTree {
    static final int COUNT = 10;
    Node root;
	
    //μ‚½μž… λ©”μ†Œλ“œ 
    void add(Integer x){
        Node newNode = new Node(x);
		
        if(root == null) {
            root = newNode;
        }

        else{
            Node node = root;
            while(true){
                if(x > node.data) {
                    if(node.right == null) break;
                    node = node.right;
                }
                else if ( x < node.data) {
                    if(node.left == null) break;
                    node = node.left;
                }
            }
            if(x > node.data) node.right = newNode;
            else node.left = newNode;
        }
    }
    
	//μ‚­μ œ λ©”μ†Œλ“œ
	void remove(int x){
        Node current = root;
        Node node = root;
        while(current.data != x){
            if(x > current.data) {
                if(x == current.right.data) {
                    node = current.right;
                    break;
                }
                current = current.right;
            }
            else {
                if(x == current.left.data) {
                    node = current.left;
                    break;
                }
                current = current.left;
            }
        }
        System.out.println(current.data);
        System.out.println(node.data);

        if(node.left == null && node.right == null) {
            System.out.println("이 λ…Έλ“œλŠ” μžμ‹μ΄ μ—†μŒ");
//            if(x > current.data)
        }
        else if (node.left != null && node.right != null){
            System.out.println("이 λ…Έλ“œλŠ” μžμ‹μ΄ λ‘˜λ‹€ 있음");
        }
        else {
            System.out.println("이 λ…Έλ“œλŠ” μžμ‹μ΄ ν•˜λ‚˜λ§Œ 있음");
        }
    }
    
    //μ „μœ„ 순회 : μœ„-μ™Ό-였
    void preOrder(Node node){
        System.out.print(node.data + " ");
        if(node.left != null) {
            preOrder(node.left);
        }
        if(node.right != null){
            preOrder(node.right);
        }
    }

	//μ€‘μœ„ 순회: μ™Ό-μœ„-였
    void inOrder(Node node){
        if(node.left != null) inOrder(node.left);
        System.out.print(node.data + " ");
        if(node.right != null)inOrder(node.right);
    }
    
    //ν›„μœ„ 순회: μ™Ό-였-μœ„
    void postOrder(Node node){
        if(node.left != null) postOrder(node.left);
        if(node.right != null)postOrder(node.right);
        System.out.print(node.data + " ");
    }
}

TreePrinter.java - 이진 트리 좜λ ₯ μ½”λ“œ

package tree;

import java.util.ArrayList;
import java.util.List;

public class TreePrinter
{
    /** Node that can be printed */
    public interface PrintableNode
    {
        /** Get left child */
        PrintableNode getLeft();


        /** Get right child */
        PrintableNode getRight();


        /** Get text to be printed */
        String getText();
    }


    /**
     * Print a tree
     *
     * @param root
     *            tree root node
     */
    public static void print(PrintableNode root)
    {
        List<List<String>> lines = new ArrayList<List<String>>();

        List<PrintableNode> level = new ArrayList<PrintableNode>();
        List<PrintableNode> next = new ArrayList<PrintableNode>();

        level.add(root);
        int nn = 1;

        int widest = 0;

        while (nn != 0) {
            List<String> line = new ArrayList<String>();

            nn = 0;

            for (PrintableNode n : level) {
                if (n == null) {
                    line.add(null);

                    next.add(null);
                    next.add(null);
                } else {
                    String aa = n.getText();
                    line.add(aa);
                    if (aa.length() > widest) widest = aa.length();

                    next.add(n.getLeft());
                    next.add(n.getRight());

                    if (n.getLeft() != null) nn++;
                    if (n.getRight() != null) nn++;
                }
            }

            if (widest % 2 == 1) widest++;

            lines.add(line);

            List<PrintableNode> tmp = level;
            level = next;
            next = tmp;
            next.clear();
        }

        int perpiece = lines.get(lines.size() - 1).size() * (widest + 4);
        for (int i = 0; i < lines.size(); i++) {
            List<String> line = lines.get(i);
            int hpw = (int) Math.floor(perpiece / 2f) - 1;

            if (i > 0) {
                for (int j = 0; j < line.size(); j++) {

                    // split node
                    char c = ' ';
                    if (j % 2 == 1) {
                        if (line.get(j - 1) != null) {
                            c = (line.get(j) != null) ? 'β”΄' : 'β”˜';
                        } else {
                            if (j < line.size() && line.get(j) != null) c = 'β””';
                        }
                    }
                    System.out.print(c);

                    // lines and spaces
                    if (line.get(j) == null) {
                        for (int k = 0; k < perpiece - 1; k++) {
                            System.out.print(" ");
                        }
                    } else {

                        for (int k = 0; k < hpw; k++) {
                            System.out.print(j % 2 == 0 ? " " : "─");
                        }
                        System.out.print(j % 2 == 0 ? "β”Œ" : "┐");
                        for (int k = 0; k < hpw; k++) {
                            System.out.print(j % 2 == 0 ? "─" : " ");
                        }
                    }
                }
                System.out.println();
            }

            // print line of numbers
            for (int j = 0; j < line.size(); j++) {

                String f = line.get(j);
                if (f == null) f = "";
                int gap1 = (int) Math.ceil(perpiece / 2f - f.length() / 2f);
                int gap2 = (int) Math.floor(perpiece / 2f - f.length() / 2f);

                // a number
                for (int k = 0; k < gap1; k++) {
                    System.out.print(" ");
                }
                System.out.print(f);
                for (int k = 0; k < gap2; k++) {
                    System.out.print(" ");
                }
            }
            System.out.println();

            perpiece /= 2;
        }
    }
}

BinarySearchTreeMain.java

package tree;

public class BinarySearchTreeMain {
    public static void main(String[] args) {
        BinarySearchTree bst = new BinarySearchTree();
        bst.add(10);

        bst.add(5);

        bst.add(7);
        bst.add(29);
        bst.add(32);
        bst.add(31);
        TreePrinter.print(bst.root);

        bst.preOrder(bst.root);
        System.out.println();
        bst.inOrder(bst.root);
        System.out.println();
        bst.postOrder(bst.root);

        bst.remove(31);
    }
}

 

μ‹€ν–‰ κ²°κ³Ό