4. Linked List

๊น€ํ˜„์šฐยท2024๋…„ 6์›” 20์ผ
0

์ž๋ฃŒ๊ตฌ์กฐ

๋ชฉ๋ก ๋ณด๊ธฐ
10/12
post-thumbnail

๐Ÿ’ป Linked List

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ž€ ์—ฐ์†์ ์ด์ง€ ์•Š์€ ๊ณต๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.
๋…ธ๋“œ ๋‹จ์œ„๋กœ ์ €์žฅ์ด ๋˜๋ฉฐ ์ด ๋…ธ๋“œ์—๋Š” ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š” ์ฐธ์กฐ์ž๊ฐ€ ์กด์žฌํ•œ๋‹ค.

์ฐธ์กฐ์ž๋ฅผ ํ†ตํ•ด ๊ฐ ๋…ธ๋“œ๋ผ๋ฆฌ ์—ฐ๊ฒฐ๋œ๋‹ค.

์ฒซ ๋…ธ๋“œ์˜ ์œ„์น˜๋ฅผ ์•Œ๊ธฐ์œ„ํ•ด Header๊ฐ€ ์กด์žฌํ•˜๋ฉฐ ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ
๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์•Œ๊ธฐ์œ„ํ•ด Tail์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

<์žฅ์ >
๋ฐฐ์—ด๊ณผ ๋‹ค๋ฅด๊ฒŒ ๊ธธ์ด์˜ ์ œํ•œ์ด ์—†๋‹ค.
์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ์‹œ ๋…ธ๋“œ์˜ ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ๋‹ค์‹œ ์ด์–ด์ฃผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋˜ํ•œ ๋ฐฐ์—ด ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ๋ฐ€๊ฑฐ๋‚˜ ๋‹น๊ธธ ํ•„์š” ์—†์ด
๋ฐ”๋กœ ์‚ญ์ œ์™€ ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

<๋‹จ์ >
์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•œ ์กฐํšŒ๊ฐ€ ๋ถˆ๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค.

๐Ÿ’ป ๊ธฐ๋Šฅ

Linked List๋„ List ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์•„ ๋งŒ๋“ค์–ด์ง„๋‹ค.
๋”ฐ๋ผ์„œ ArrayList์™€ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์€ ๋น„์Šทํ•˜๋ฉฐ

๊ตฌํ˜„๋˜ํ•œ ๋™์ผํ•˜๊ฒŒ ํ•  ๊ณ„ํš์ด๋‹ค.

ํฌ์ธํ„ฐ๊ฐ€ ์—†์ด ์ €๊ฑธ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋‚˜ ์‹ถ์ง€๋งŒ ์‚ฌ์‹ค ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

๐Ÿ“– ์ฐธ์กฐ์ž๋ฃŒํ˜•

์ฐธ์กฐ ์ž๋ฃŒํ˜•์€ Heap์˜์—ญ์— ๋™์  ํ• ๋‹น๋˜๋ฉฐ ๋™์ ํ• ๋‹น ๋œ ์˜์—ญ์˜ ์‹œ์ž‘์ฃผ์†Œ๊ฐ€
์Šคํƒ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ฆ‰, C์—์„œ ๋™์ ํ• ๋‹น์„ ํ•˜๋Š” ๊ฒƒ์ด๋ž‘ ๊ฐ™์€ ๋ฐฉ์‹์ด๋‹ค.

์šฐ๋ฆฌ๊ฐ€ String str=new String("์–ด์ฉ”ํ‹ฐ๋น„");
๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด Heap์˜์—ญ์— ์–ด์ฉ”ํ‹ฐ๋น„ ๋ผ๋Š” ๋ฌธ์ž์—ด ์ƒ์ˆ˜๊ฐ€ ์ €์žฅ๋˜๊ณ 

์ด ์ƒ์ˆ˜์˜ ์‹œ์ž‘์ฃผ์†Œ๋ฅผ str์— ๋ณต์‚ฌํ•˜์—ฌ ์ €์žฅํ•œ๋‹ค.

ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ์—๋Š”

Stack (main method)          Heap
----------------------       ------------------------
| myObject (0x1a2b) | -----> | MyClass (0x1a2b)      |
|                   |        | intValue: 10          |
|                   |        | doubleValue: 20.5     |
|                   |        | stringValue: "Hello"  |
----------------------       ------------------------



์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์Šคํƒ์—๋Š” ํด๋ž˜์Šค์˜ ์ฃผ์†Œ๊ฐ€ ๊ทธ ๋‚ด๋ถ€์—๋Š” ๋‹ค์–‘ํ•œ ๋ฉค๋ฒ„๋ณ€์ˆ˜,๋งค์†Œ๋“œ ๋“ฑ์ด ์กด์žฌํ•œ๋‹ค.

๐Ÿ“– ์ฐธ์กฐ์ž๋ฃŒํ˜•์˜ Call by Value

์ฐธ์กฐ์ž๋ฃŒํ˜•์€ ์–ธ๋œป ๋ณด๋ฉด Call by Reference ๋ฐฉ์‹์ธ ๊ฒƒ ๊ฐ™์œผ๋‚˜ ์‹ค์ƒ์€ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.


public class Member {
    public String name;
}

public void change(Member m) {
    m.name = "๊น€๋ฏผ์ˆ˜";
}

๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋Š” Member ํด๋ž˜์Šค๋ฅผ ๋ฐ›์•„ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค.

Main์—์„œ ์‹คํ–‰ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ด๋ฆ„๊ฐ’์ด ๋ฐ”๋€œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


public static void main(String[] args) {
    Member member = new Member();
    member.name = "์ด์˜ํฌ";

    change(member);

    System.out.println(member.name); // ์ถœ๋ ฅ ๊ฒฐ๊ณผ: "๊น€๋ฏผ์ˆ˜"
}


์ด๊ฑธ ๋ณด๊ณ  ์ž๋ฐ”๋„ Call by Reference๋ฅผ ์ง€์›ํ•˜๋Š”๊ตฌ๋‚˜! ์‹ถ์ง€๋งŒ ์‹ค์ƒ์€ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.

์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด ์ž๋ฐ”์˜ ์ฐธ์กฐ์ž๋ฃŒํ˜•์€ ํž™์— ์ €์žฅ๋˜๋ฉฐ ๊ทธ ์ฃผ์†Œ๋งŒ ์Šคํƒ์— ์ €์žฅ๋œ๋‹ค. 
์šฐ๋ฆฌ๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ฐธ์กฐ์ž๋ฃŒํ˜•์„ ๋„˜๊ฒจ์ค„ ๋•Œ ์‚ฌ์‹ค์€ ์ด ์Šคํƒ์— ์ €์žฅ๋œ ์ฃผ์†Œ๊ฐ’์ด ๋ณต์‚ฌ๋˜์–ด ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์ด ์ฃผ์†Œ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ name์„ ๋ณ€๊ฒฝํ•˜๋ผ๋Š” ๋ช…๋ น์ด๊ธฐ์— ๋ณ€๊ฒฝ๋œ ๊ฒƒ์ด๋‹ค. 

๋งŒ์•ฝ ๋ฉ”์†Œ๋“œ๊ฐ€

public void change(Member m) {
    m = new Member();
    m.name = "๊น€๋ฏผ์ˆ˜";
}

์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒˆ๋กœ์šด Member ํด๋ž˜์Šค๋กœ ๊ฐˆ์•„๋ผ์šฐ๋ ค ํ•œ๋‹ค๋ฉด ๋ณ€ํ™”ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

๐Ÿ“– ๊ทธ๋ฆผ์œผ๋กœ ์„ค๋ช…

๋ณ€๊ฒฝ ์ „
Stack                    Heap
-----------------       ---------------------
| member (0x1a2b) | ---> | Member object     |
-----------------       | name: "์ด์˜ํฌ"    |
                        ---------------------
๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์‹œ
Stack (change method)   Stack (main method)     Heap
----------------------  -----------------       ---------------------
| m (0x1a2b)          | ---> | member (0x1a2b) | ---> | Member object |
----------------------  -----------------      | name: "์ด์˜ํฌ"        |
                                                ---------------------

m.name = "๊น€๋ฏผ์ˆ˜" ์ˆ˜ํ–‰ ํ›„
๋ณ€๊ฒฝ ํ›„
Stack                    Heap
-----------------       ---------------------
| member (0x1a2b) | ---> | Member object     |
-----------------       | name: "๊น€๋ฏผ์ˆ˜"    |
                        ---------------------

๐Ÿ’ป ์ „์ฒด ๊ตฌํ˜„

java์—์„œ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ ์ฒ˜๋Ÿผ ์–‘๋ฐฉํ–ฅ LinkedList๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž.

๐Ÿ“– Node

private class Node{
        //1. ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ ๊ฐ€๋Šฅํ•ด์•ผํ•จ
        //2. ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฅด์ผœ์•ผํ•จ ๋‹จ ํฌ์ธํ„ฐ๋Š” ์—†์Œ;; ๋˜๊ฒŒ ๋ถˆํŽธํ•˜๋„ค
        private Object data;
        private Node nextNode;//๋‚จ๋“ค์€ ์ฐธ์กฐ ๋ถˆ๊ฐ€
        private Node prevNode;

        public Node(){
            this.data=null;
            this.nextNode=null;
            this.prevNode=null;
        }//๋…ธ๋“œ ์ƒ์„ฑ์‹œ ์ดˆ๊ธฐํ™”

        public Node(Object input){
            this.data=input;
            this.nextNode=null;
            this.prevNode=null;
        }//๊ฐ’ ์ž…๋ ฅ์‹œ ๊ฐ’ ๋ฐ˜์˜ํ•˜์—ฌ ์ดˆ๊ธฐํ™”

        @Override
        public String toString(){
            return String.valueOf(this.data);
        }
    }

๐Ÿ“– Header์™€ Tail

LinkedList ํด๋ž˜์Šค ์„ ์–ธ์‹œ ์ž๋™์œผ๋กœ
Head์™€ Tail์ด ์„œ๋กœ๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ฒŒ ํ•ด์•ผํ•จ.


public class customLinkedList {
    private Node Head;
    private Node Tail;
    
     customLinkedList(){
        Head=new Node();
        Tail=new Node();

        Head.nextNode=Tail;
        Tail.prevNode=Head;
    }
}//์ด๋ฅผ ์œ„ํ•ด ์ƒ์„ฑ์ž์— ํด๋ž˜์Šค ์ƒ์„ฑ์‹œ ์ž๋™์œผ๋กœ Node๋ฅผ ํ• ๋‹น๋ฐ›์•„ ์„œ๋กœ ์—ฐ๊ฒฐํ•˜๊ฒŒ ํ•ด์คŒ

๐Ÿ“– addFirst์™€ addLast

1. ์ดˆ๊ธฐ์ƒํƒœ์—์„œ ์‚ฝ์ž…์‹œ

์œ„์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋„๊ณ  ์žˆ์„๊ฒƒ์ด๋‹ค.

์ด๋•Œ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.

์ด ๊ตฌ์กฐ์—์„œ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”

Head.nextNode๋ฅผ newNode์— ์—ฐ๊ฒฐํ•˜๊ณ 
Tail.prevNode๋ฅผ newNode์— ์—ฐ๊ฒฐํ•ด์•ผ ํ• ๊ฒƒ์ด๋‹ค.

์ฆ‰ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ์ƒˆ๋กœ ์‚ฝ์ž…์„ ํ•ด์•ผํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋” ํ™•์žฅ์„ ํ•ด๋ณด์ž.
์ดˆ๊ธฐ ์ƒํƒœ์—์„œ ์ข€๋” ์ง„ํ–‰๋ฌ์„ ๊ฒฝ์šฐ๋ผ๊ณ  ํ•ด๋ณด์ž.

๋งŒ์•ฝ ์ด๋Ÿฐ์‹์ด๋ผ๋ฉด? Tail์€ ์ €~~ ๋’ค์— ์กด์žฌํ•œ๋‹ค๋ฉด?

์ด๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” Head๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€ ์ผ ๊ฒƒ์ด๋‹ค.


๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” Head์™€ Tail๋งŒ์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋‚ด์–ด์•ผ ํ•œ๋‹ค.

์ดˆ๊ธฐ ์ƒํƒœ์—์„œ Head.nextNode == anotherNode๋ฅผ

anotherNode.prevNode=Head๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋‹ค.

๋งŒ์•ฝ Head.nextNode=newNode๋ฅผ ๋จผ์ € ์—ฐ๊ฒฐ์‹œ์ผœ๋ฒ„๋ฆฐ๋‹ค๋ฉด
anotherNode์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์œ ์‹คํ•  ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” anotherNode๋ฅผ Head๋ฅผ ํ†ตํ•ด ๋จผ์ € newNode์™€ ์—ฐ๊ฒฐํ•ด์•ผํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ Head์™€ newNode๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.

๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋˜‘๊ฐ™์€ ์›๋ฆฌ๋กœ anotherNode๋ถ€ํ„ฐ ์—ฐ๊ฒฐํ›„ Tail์„ ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ์ฝ”๋“œ๋กœ ์“ฐ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๊ตฌํ˜„
public void addFirst(Object obj){
        Node newNode=new Node(obj);

        Head.nextNode.prevNode=newNode;
        newNode.nextNode=Head.nextNode;//another Node๋ถ€ํ„ฐ ์—ฐ๊ฒฐ

        Head.nextNode=newNode;
        newNode.prevNode=Head;

        size++;
    }

    public void addLast(Object obj){
        Node newNode=new Node(obj);

        Tail.prevNode.nextNode=newNode;
        newNode.prevNode=Tail.prevNode;//another Node๋ถ€ํ„ฐ ์—ฐ๊ฒฐ

        Tail.prevNode=newNode;
        newNode.nextNode=Tail;

        size++;
    }

๊ฒฐ๊ณผ
public static void main(String[] args) {
        customLinkedList cLinkedList=new customLinkedList();

        cLinkedList.addFirst(1);
        cLinkedList.addFirst(2);
        cLinkedList.addFirst(3);
        cLinkedList.addFirst(4);
        cLinkedList.addFirst(5);

        cLinkedList.addLast(1);
        cLinkedList.addLast(2);
        cLinkedList.addLast(3);
        cLinkedList.addLast(4);
        cLinkedList.addLast(5);

        cLinkedList.printAll();
    }
    
     public void printAll(){
        int i=0;
        for(Node tmp=Head.nextNode;tmp.nextNode!=null;tmp=tmp.nextNode,i++)
            System.out.println(i+"๋ฒˆ์งธ ๋ฐ์ดํ„ฐ"+tmp.data);
    }
    
    ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ถœ๋ ฅ์‹œ ์‚ฌ์ง„๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ด์„ ํ™•์ธํ• ์ˆ˜์žˆ๋‹ค.

๐Ÿ“– add

์›ํ•˜๋Š” ์œ„์น˜์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” add๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž.

์ด๋ฅผ ์œ„ํ•ด ์›ํ•˜๋Š” ์ธ๋ฑ์Šค์˜ ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” node ๋งค์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

private Node node(int index){
        if(index>size)
            return null;

        Node tmp=Head;

        for(int i=0;i<=index;i++)
            tmp=tmp.nextNode;

        return tmp;
    }//i๋ฒˆ์งธ ๋…ธ๋“œ ๋ฐ˜ํ™˜ํ•˜๊ธฐ 
    
์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ add๊ตฌํ˜„ํ•œ๋‹ค.

์œ„์—์„œ๋Š” index์— ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋งŒ์•ฝ add์—์„œ 2๋ฒˆ์งธ ์ธ๋ฑ์Šค์— 3์„ ์ €์žฅํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด
ํ˜„์žฌ 2๋ฒˆ ์œ„์น˜์˜ ๋…ธ๋“œ๋Š” ๋ฐ€๋ ค์„œ 3๋ฒˆ์ด ๋˜๊ณ   newNode๊ฐ€ 2๋ฒˆ์ด ๋˜์–ด์•ผํ•œ๋‹ค.

์ฆ‰, ์œ„์—์„œ 2๋ฒˆ์„ ์ฐพ์€ํ›„ Tail์„ ์—ฐ๊ฒฐ์‹œํ‚ค๋“ฏ์ด ๋˜‘๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค.
๊ตฌํ˜„ ๋ฐ ๊ฒฐ๊ณผ
public static void main(String[] args) {
        customLinkedList cLinkedList=new customLinkedList();

        cLinkedList.addFirst(1);
        cLinkedList.addFirst(2);
        cLinkedList.addFirst(3);
        cLinkedList.addFirst(4);
        cLinkedList.addFirst(5);

        cLinkedList.addLast(1);
        cLinkedList.addLast(2);
        cLinkedList.addLast(3);
        cLinkedList.addLast(4);
        cLinkedList.addLast(5);

        cLinkedList.printAll();

        cLinkedList.add(3,"์–ด์ฉ”ํ‹ฐ๋น„");
        cLinkedList.printAll();

        
    }

public void add(int index,Object obj){
        Node base=node(index);
        Node newNode=new Node(obj);

        base.prevNode.nextNode=newNode;
        newNode.prevNode=base.prevNode;//another Node๋ถ€ํ„ฐ ์—ฐ๊ฒฐ

        base.prevNode=newNode;
        newNode.nextNode=base;
    }
    

https://github.com/Rachi3/dataStructure/tree/master/3.LinkedList

๋‚จ์€ ๋ถ€๋ถ„ ๊ตฌํ˜„๋œ ๋งํฌ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€