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

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ (Binary search tree) BST - ์ž๋ฃŒ๊ตฌ์กฐ

by sh119 2024. 7. 3.

๐Ÿ‘ฉ‍๐Ÿ’ป Binary search ree๋ž€?

์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋Š” ์•„๋ž˜์˜ ๊ทœ์น™์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ด์ง„ ํŠธ๋ฆฌ์ด๋‹ค.

  1. ์™ผ์ซ€ ์ž์‹ ๋…ธ๋“œ์˜ ํ‚ค๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ‚ค ๋ณด๋‹ค ์ž‘์Œ
  2. ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ ํ‚ค๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ‚ค๋ณด๋‹ค ํผ
  3. ๊ฐ๊ฐ์˜ ์„œ๋ธŒ ํŠธ๋ฆฌ๋„ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ๋ฅผ ์œ ์ง€
  4. ์ค‘๋ณต๋œ ํ‚ค๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Œ

โœ๏ธ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ํŠน์ง•

  • ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ ๊ทœ์น™์— ์˜ํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ ฌ๋จ
  • ์ด์ง„ ํŠธ๋ฆฌ์— ๋น„ํ•ด ํƒ์ƒ‰์ด ๋น ๋ฆ„ (๊ท ํ˜• ์œ ์ง€ ํ•„์š”)
    • ๊ท ํ˜• ์ƒํƒœ : O(logN)
    • ๋ถˆ๊ท ํ˜• ์ƒํƒœ : O(N)

โœ๏ธ ํƒ์ƒ‰

  1. ์ฐพ๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ๋น„๊ต ์‹œ์ž‘
  2. ๋Œ€์†Œ ๋น„๊ต๋ฅผ ํ•˜์—ฌ ์ฐพ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ž‘์œผ๋ฉด ์™ผ์ชฝ, ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋กœ ์ด๋™
  3. ์ฐพ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด null ๋ฐ˜ํ™˜
  4. ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๋”๋ผ๋„ ์ตœ๋Œ€ ํŠธ๋ฆฌ ๋†’์ด ๋งŒํผ์˜ ํƒ์ƒ‰์ด ์ด๋ฃจ์–ด์ง

 

โœ๏ธ ์‚ฝ์ž…

  1. Root ๋ถ€ํ„ฐ ๋น„๊ต ์‹œ์ž‘ (์ค‘๋ณต ํ‚ค ๋ฐœ๊ฒฌ ์‹œ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ์ข…๋ฃŒ)
  2. ์‚ฝ์ž…ํ•  ํ‚ค๊ฐ€ ํ˜„์žฌ ๋…ธ๋“œ์˜ ํ‚ค๋ณด๋‹ค ์ž‘์œผ๋ฉด ์™ผ์ชฝ์œผ๋กœ ์ด๋™
  3. ์‚ฝ์ž…ํ•  ํ‚ค๊ฐ€ ํ˜„์žฌ ๋…ธ๋“œ์˜ ํ‚ค๋ณด๋‹ค ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™
  4. Leaf ๋…ธ๋“œ์— ๋„๋‹ฌ ํ›„ ํ‚ค ๋น„๊ตํ•˜์—ฌ ์ž‘์œผ๋ฉด ์™ผ์ชฝ, ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ์— ์‚ฝ์ž…

 

โœ๏ธ ์‚ญ์ œ

  • ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ๊ฐ€ Leaf ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ
    1. ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ ์‚ญ์ œ
    2. ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ•ด๋‹น ์ž์‹ ๋งํฌ null๋กœ ๋ณ€๊ฒฝ

 

  • ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ์— ์ž์‹ ๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜ ์žˆ๋Š” ๊ฒฝ์šฐ
    1. ์ž์‹ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ
    2. ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ ์‚ญ์ œ

 

  • ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ์— ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋‘˜์ธ ๊ฒฝ์šฐ
    1. ๋…ธ๋“œ ์„ ํƒ
      • ๋ฐฉ๋ฒ•1) ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์„œ๋ธŒ ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ํฐ ๋…ธ๋“œ ์„ ํƒ
      • ๋ฐฉ๋ฒ•2) ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ์ž‘์€ ๋…ธ๋“œ ์„ ํƒ
    2. ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ค‘ ์„ ํƒํ•œ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ ์œ„์น˜๋กœ ์˜ฌ๋ฆผ (**์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์˜ ํŠน์„ฑ ์œ ์ง€๋ฅผ ์œ„ํ•ด)
    3. ์œ„๋กœ ์˜ฌ๋ฆฌ๋Š” ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ์ž์‹ ๋…ธ๋“œ๋“ค์˜ ๋งํฌ ์—ฐ๊ฒฐ ์ž‘์—… ์ง„ํ–‰
    4. ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ ์‚ญ์ œ

 

โœ๏ธ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ ์ฝ”๋“œ ๊ตฌํ˜„

1) ๊ธฐ๋ณธ ๊ตฌํ˜„

package algorithmBasic.tree;

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

    Node(int key, Node left, Node right){
        this.key = key;
        this.left = left;
        this.right = right;
    }

}
public class BinarySearchTree {
    Node head;

    BinarySearchTree(int key){
        this.head = new Node(key, null, null);
    }

    public void addNode(int key){
        if(this.head == null){
            this.head = new Node(key, null, null);
        }else{
            Node cur = this.head;

            while(true){
                Node pre = cur;

                if(key < cur.key) {
                    cur = cur.left;

                    if (cur == null) {
                        pre.left = new Node(key, null, null);
                        break;
                    }
                }
                else{
                    cur = cur.right;

                    if(cur == null){
                        pre.right = new Node(key, null, null);
                        break;
                    }
                }
            }
        }
    }

    public void removeNoe(int key){
        Node parent = null;
        Node successor = null;
        Node predecessor = null;
        Node child = null;

        Node cur = this.head;
        while(cur != null){
            if(key == cur.key){
                break;
            }
            parent = cur; //cur์œ„์น˜ ๋ณ€ํ™˜ ์œ„์— ์žˆ์œผ๋ฏ€๋กœ ์ข…๋ฃŒ์‹œ cur์˜ ๋ถ€๋ชจ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.

            if(key < cur.key){
                cur = cur.left;
            }else{
                cur = cur.right;
            }
        }
        if(cur == null){
            System.out.println("key์— ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.");
            return;
        }

        // Leaf ๋…ธ๋“œ ์ธ ๊ฒฝ์šฐ
        if(cur.left == null && cur.right == null){
            if(parent == null){ // ์‚ฌ์‹ค์ƒ ํŠธ๋ฆฌ์— ๋…ธ๋“œ๊ฐ€ ํ•œ ๊ฐœ์ธ ์ผ€์ด์Šค
                this.head = null;
            }else{
                if(parent.left == cur){
                    parent.left = null;
                }else{
                    parent.right = null;
                }
            }
        }
        // ์ž์‹ ๋…ธ๋“œ๊ฐ€ ํ•œ ๊ฐœ์ธ ๊ฒฝ์šฐ
        else if((cur.left != null && cur.right == null)
            || (cur.left == null && cur.right != null)){
            if(cur.left != null){
                child = cur.left;
            }else{
                child = cur.right;
            }
            if(parent == null){ // cur์ด ๋ฃจํŠธ๋…ธ๋“œ์ด๊ณ , ๋ฃจํŠธ๋…ธ๋“œ์— ์ž์‹์ด ํ•˜๋‚˜ ์žˆ๋Š” ๊ฒฝ์šฐ
                this.head = child;
            }else{
                if(parent.left == cur){
                    parent.left = child;
                }else{
                    parent.right = child;
                }
            }
        }
        // ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋‘˜ ์ธ ๊ฒฝ์šฐ (์ œ์ผ ๋ณต์žกํ•œ)
        else{
            predecessor = cur;
            successor = cur.left; // ์‚ญ์ œ ๋Œ€์ƒ ๋…ธ๋“œ๊ธฐ์ค€ ์™ผ์ชฝ์—์„œ ์ œ์ผ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๊ฒƒ ๋นผ์˜ค๊ธฐ

            while(successor.right != null){
                predecessor = successor;
                successor = successor.right;
            }
            predecessor.right = successor.left;
            successor.left = cur.left;
            successor.right = cur.right;

            if(parent == null){
                this.head = successor;
            }else{
                if(parent.left == cur){
                    parent.left = successor;
                }else{
                    parent.right = successor;
                }
            }
        }
    }

}

 

2) ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ ๊ตฌํ˜„

package algorithmBasic.tree;

public class BinarySearchTree2 {
    Node head;

    BinarySearchTree2(int key){
        this.head = new Node(key, null, null);
    }

    public Node addNodeRecursive(Node cur, int key){
        if(cur == null){
            return new Node(key, null, null);
        }
        if(key < cur.key){
            cur.left = addNodeRecursive(cur.left, key);
        }else{
            cur.right = addNodeRecursive(cur.right, key);
        }

        return cur;
    }

    public Node removeNodeRecursive(Node cur, int key){
        if(cur == null){
            return null;
        }
        if(key < cur.key){
            cur.left = removeNodeRecursive(cur.left, key);
        }else if(key > cur.key){
            cur.right = removeNodeRecursive(cur.right, key);
        }else{
            if(cur.left == null){ // ์ž์‹๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜ ์žˆ๊ฑฐ๋‚˜, ์—†๋Š” ๊ฒฝ์šฐ
                return cur.right;
            }else if(cur.right == null){
                return cur.left;
            }else{
                Node predecessor = cur;
                Node successor = cur.left;

                while(successor.right != null){
                    predecessor = successor;
                    successor = successor.right;
                }
                predecessor.right = successor.left;
                cur.key = successor.key;
            }
        }
        return cur;
    }

    // levelOrder : Queue ์ด์šฉํ•ด์„œ ์ถœ๋ ฅ
}