์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ž€?

๋ฐฐ์—ด๊ณผ ๋‹ค๋ฅด๊ฒŒ ์—ฐ์†์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜์— ์ €์žฅ๋˜์ง€ ์•Š๋Š” ์„ ํ˜• ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ด๋ฉฐ, ๊ฐ ๋…ธ๋“œ๋Š” ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•ด ์„œ๋กœ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์ ‘๊ทผํ•œ๋‹ค.

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ํŠน์ง•

์žฅ์ 

  1. ๋ฐฐ์—ด๊ณผ ๋‹ค๋ฅด๊ฒŒ ์š”์†Œ์˜ ์ˆ˜๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น๋ฐ›์„ ํ•„์š”๊ฐ€ ์—†๋‹ค.
  2. ๋ฐฐ์—ด๊ณผ ๋‹ค๋ฅด๊ฒŒ ๊ณต๊ฐ„์„ ์ถ”๊ฐ€๋กœ ํ• ๋‹น๋ฐ›๊ฑฐ๋‚˜ ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ๋“ค์˜ ์œ„์น˜๋ฅผ ์ด๋™์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์—†์–ด์„œ ์‚ฝ์ž… ๋ฐ ์‚ญ์ œ๊ฐ€ ์šฉ์ดํ•˜๋‹ค.

 

๋‹จ์ 

  1. ๋ฐฐ์—ด๊ณผ ๋‹ค๋ฅด๊ฒŒ ํŠน์ • ์ธ๋ฑ์Šค์˜ ์œ„์น˜์— O(1)์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๊ณ  ์•ž์—์„œ๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ์š”์†Œ๋ฅผ ํƒ์ƒ‰ํ•ด์•ผํ•œ๋‹ค.
  2. ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ํฌ์ธํ„ฐ ๋ณ€์ˆ˜์˜ ๊ณต๊ฐ„๋„ ์ถ”๊ฐ€์ ์œผ๋กœ ํ•„์š”ํ•˜๋‹ค.

์ฝ”๋“œ๋กœ ๋ณด๋Š” ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

๋…ธ๋“œ ๊ตฌํ˜„

class Node {
    private Node left;
    private Node right;
    private final int data;

    public Node(int data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

    public int getData() {
        return data;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public void setRight(Node right) {
        this.right = right;
    }
}
  1. ๋…ธ๋“œ ํด๋ž˜์Šค๋Š” ์™ผ์ชฝ ๋…ธ๋“œ์™€ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ์ฐธ์กฐ ๋ณ€์ˆ˜์™€ ๋ณด๊ด€ํ•  ๋ฐ์ดํ„ฐ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„

class LinkedList {
    private Node head;
    private Node tail;

...
}
  1. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋Š” ๋งจ ์ฒ˜์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” head์™€ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” tail์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  2. ๋งจ ์ฒ˜์Œ ์•„๋ฌด๋Ÿฐ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” head์™€ tail์ด null์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋œ๋‹ค.

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ ์ถ”๊ฐ€ ๊ตฌํ˜„

    public void addFirst(int data) {
        Node node = new Node(data);
        if(isEmpty()) {
            head = tail = node;
        }
        else {
            node.setRight(head);
            head.setLeft(node);
            head = node;
        }
    }

    public void addLast(int data) {
        Node node = new Node(data);
        if(isEmpty()) {
            head = tail = node;
        }
        else {
            tail.setRight(node);
            node.setLeft(tail);
            tail = node;
        }
    }
  1. ๊ฐ๊ฐ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด node๋ฅผ ๋„ฃ๋Š” ๋ฉ”์„œ๋“œ์™€ ๋งจ ๋’ค์— ์ƒˆ๋กœ์šด node๋ฅผ ๋„ฃ๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
  2. ๋งŒ์•ฝ LinkedList๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด head์™€ tail์— ์ƒˆ๋กœ์šด node๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ณ€์ˆ˜๋“ค์„ ์ดˆ๊ธฐํ™” ํ•ด์•ผํ•œ๋‹ค. 
  3. ๋งŒ์•ฝ LinkedList๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด, head์— ์žˆ๋Š” node๋ฅผ ์ƒˆ๋กœ์šด node์˜ ์˜ค๋ฅธ์ชฝ์— ์œ„์น˜ํ•˜๋„๋ก ์ฐธ์กฐ ๋ณ€์ˆ˜๋“ค์„ ์กฐ์ •ํ•œ ํ›„ ๊ธฐ์กด head์— ์ƒˆ๋กœ์šด node๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ์ค€๋‹ค. 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ ์ œ๊ฑฐ ๊ตฌํ˜„

    public void remove(int data) {
        Node node = head;
        while(node != null) {
            if(node.getData() == data) {
                if(node == head) {
                    if(node.getRight() != null) {
                        head = node.getRight();
                        node.getRight().setLeft(null);
                    }
                    else {
                        head = tail = null;
                    }
                }
                else if(node == tail){
                    tail = node.getLeft();
                    node.getLeft().setRight(null);
                }
                else {
                    node.getLeft().setRight(node.getRight());
                    node.getRight().setLeft(node.getLeft());
                }

                node = null;
                break;
            }

            node = node.getRight();
        }
    }
  1. head์™€ tail์„ ๋”๋ฏธ ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‹ค์ œ ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•˜์—ฌ remove ๋ฉ”์„œ๋“œ๊ฐ€ ๊ต‰์žฅํžˆ ๊ธธ์–ด์กŒ๋‹ค.
  2. head์™€ tail์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ์˜๋ฏธ ์žˆ๋Š” ๋…ธ๋“œ์ด๋ฏ€๋กœ, ์‚ญ์ œํ•  ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŽ์€ ์กฐ๊ฑด์„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.   

 

์ฒซ๋ฒˆ์งธ. ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ head์ธ๊ฐ€? 

๋‘๋ฒˆ์งธ. ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ tail์ธ๊ฐ€? 

์„ธ๋ฒˆ์งธ. ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ head, tail๋„ ์•„๋‹Œ ์ผ๋ฐ˜ ๋…ธ๋“œ์ธ๊ฐ€? 

 

์œ„์˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๊ตฌํ˜„ ํ•ด์•ผํ•˜๋Š” ๋กœ์ง์ด ๋‹ฌ๋ผ์ง„๋‹ค.

์ฒซ๋ฒˆ์งธ ์กฐ๊ฑด์˜ ๊ฒฝ์šฐ head์˜ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ head๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค. ๋˜ ๋งŒ์•ฝ์— LinkedList์— head ๋…ธ๋“œ ๋ฐ–์— ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด head๋ฅผ ๋‹จ์ˆœํžˆ null๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. 

๋‘๋ฒˆ์งธ ์กฐ๊ฑด์˜ ๊ฒฝ์šฐ tail์„ ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์™ผ์ชฝ์œผ๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค. ์ด๋ฏธ head์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜๋ฐ–์— ์—†๋Š” ๊ฒฝ์šฐ(head==tail)๋ฅผ ์ฒดํฌํ•ด์คฌ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ถ€๋ถ„์€ ์‹ ๊ฒฝ์จ์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค. 

์„ธ๋ฒˆ์งธ ์กฐ๊ฑด์ธ ๊ฒฝ์šฐ ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์–‘์ชฝ ๋…ธ๋“œ๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค. 

 

๋งŒ์•ฝ head์™€ tail์„ ๋”๋ฏธ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹จ์ˆœํžˆ ์„ธ๋ฒˆ์งธ ์กฐ๊ฑด๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. 

 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์ „์ฒด ์ฝ”๋“œ

class Node {
    private Node left;
    private Node right;
    private final int data;

    public Node(int data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

    public int getData() {
        return data;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public void setRight(Node right) {
        this.right = right;
    }
}

class LinkedList {
    private Node head;
    private Node tail;

    public LinkedList() {
        head = null;
        tail = null;
    }

    public void addFirst(int data) {
        Node node = new Node(data);
        if(isEmpty()) {
            head = tail = node;
        }
        else {
            node.setRight(head);
            head.setLeft(node);
            head = node;
        }
    }

    public void addLast(int data) {
        Node node = new Node(data);
        if(isEmpty()) {
            head = tail = node;
        }
        else {
            tail.setRight(node);
            node.setLeft(tail);
            tail = node;
        }
    }

    public void remove(int data) {
        Node node = head;
        while(node != null) {
            if(node.getData() == data) {
                if(node == head) {
                    if(node.getRight() != null) {
                        head = node.getRight();
                        node.getRight().setLeft(null);
                    }
                    else {
                        head = tail = null;
                    }
                }
                else if(node == tail){
                    tail = node.getLeft();
                    node.getLeft().setRight(null);
                }
                else {
                    node.getLeft().setRight(node.getRight());
                    node.getRight().setLeft(node.getLeft());
                }

                node = null;
                break;
            }

            node = node.getRight();
        }
    }

    public boolean isEmpty() {
        return head == null;
    }
 }