Skip to content

Latest commit

ย 

History

History
307 lines (216 loc) ยท 8.23 KB

LinkedList.md

File metadata and controls

307 lines (216 loc) ยท 8.23 KB

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

written by sohyeon, hyemin ๐Ÿ’ก


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

๋จผ์ €, ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

์œ„์˜ ๊ทธ๋ฆผ ์ฒ˜๋Ÿผ ์ˆœ์„œ๊ฐ€ ์žˆ์œผ๋ฉฐ ๊ฐ๊ฐ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜์—ด๋˜์–ด ์žˆ๋Š” ํ˜•ํƒœ์ด๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋‚˜์—ด๋œ ๋ถˆ์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•œ ํ˜•ํƒœ์ด๋‹ค.

๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ์™€ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ํ•œ ์ค„๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค.
์ด๋•Œ ๋ฆฌ์ŠคํŠธ์˜ ๋ฐ์ดํ„ฐ๋Š” ๋…ธ๋“œ ๋˜๋Š” ์š”์†Œ๋ผ๊ณ  ํ•œ๋‹ค.
๊ฐ๊ฐ์˜ ๋…ธ๋“œ๋Š” ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. (์œ„์˜ ๊ทธ๋ฆผ์—์„œ ํšŒ์ƒ‰ ์„ )

ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ”๋กœ ์•ž์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์•ž์ชฝ ๋…ธ๋“œ(predecessor node), ๋ฐ”๋กœ ๋’ค์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ๋‹ค์Œ ๋…ธ๋“œ(successor node)๋ผ๊ณ  ํ•œ๋‹ค.

< ๋ฐฐ์—ด์˜ ๋‹จ์  >
    
- ํฌ๊ธฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.
- ๋น„์ˆœ์ฐจ์ ์ธ ๋ฐ์ดํ„ฐ์˜ ์ถ”๊ฐ€, ์‚ญ์ œ์— ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฐ๋‹ค.  
  (๋ฐฐ์—ด ์ค‘๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ๋นˆ์ž๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ, ์ด๋™ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.)

-> ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ์ด๋Ÿฌํ•œ ๋ฐฐ์—ด์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•œ๋‹ค.
   ๋ฐฐ์—ด์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌ, ์ด๋™ํ•˜๋Š” ๊ณผ์ • ์—†์ด ๋…ธ๋“œ ๊ฐ„์˜ ์ฐธ์กฐ ๋ณ€๊ฒฝ๋งŒ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€, ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.  

2. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ

ํฌ์ธํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

2-1. ๋…ธ๋“œ ๋งŒ๋“ค๊ธฐ

๋…ธ๋“œ ๊ฐ์ฒด์—๋Š” ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

class Node<E>{
  E data;       // ๋ฐ์ดํ„ฐ
  Node<E> next; // ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
}

next๋Š” ์ž๊ธฐ ์ž์‹ ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šคํ˜•์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•œ ์ฐธ์กฐํ˜• ํ•„๋“œ์ด๋‹ค.
Node๋Š” ์ œ๋„ค๋ฆญ์œผ๋กœ ๊ตฌํ˜„๋˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ํ˜• E๋Š” ์ž„์˜์˜ ํด๋ž˜์Šคํ˜•์ด ํ—ˆ์šฉ๋œ๋‹ค.
ํ•„๋“œ dataํ˜•์ธ E๋Š” ์ฐธ์กฐํ˜•์ด๋ผ๋Š” ๊ฒƒ์— ์œ ์˜ํ•˜์ž.

2-2. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํด๋ž˜์Šค

import java.util.Comparator;

public class LinkedList<E>{
  //๋…ธ๋“œ
  class Node<E>{
    E data;
    Node<E> next;

    //์ƒ์„ฑ์ž
    Node(E data, Node<E> next){
      this.data = data;
      this.next = next;
    }
  }

  private Node<E> head;   //๋จธ๋ฆฌ ๋…ธ๋“œ
  private Node<E> crnt;   //์„ ํƒ ๋…ธ๋“œ
}

์ƒ์„ฑ์ž

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

๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜๋„ ์—†๋Š” ๋น„์–ด ์žˆ๋Š” ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑ

  • ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ๋Š” ๊ฒฝ์šฐ

    • head == null
  • ๋…ธ๋“œ๊ฐ€ ํ•œ๊ฐœ์ธ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

    • head.next == null
  • ๊ผฌ๋ฆฌ ๋…ธ๋“œ์ธ์ง€ ํŒ๋‹จ

    • p.next == null

2-3. ๋ฉ”์†Œ๋“œ

1) ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ (Search)

search๋ฉ”์„œ๋“œ๋Š” ๊ฒ€์ƒ‰ํ•  ๋…ธ๋“œ๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๋จธ๋ฆฌ๋…ธ๋“œ๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋“ค์„ ์Šค์บ”ํ•œ๋‹ค.
๊ฒ€์ƒ‰ํ•  ๋…ธ๋“œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๊ณ  ๊ผฌ๋ฆฌ ๋…ธ๋“œ๋ฅผ ์ง€๋‚˜๊ธฐ ์ง์ „์ธ ๊ฒฝ์šฐ๋‚˜ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด ๋…ธ๋“œ๋ฅผ ์ฐพ์€ ๊ฒฝ์šฐ ์ข…๋ฃŒ๋œ๋‹ค.

public E search(E obj, Comparator<? super E> c){
  Node<E> ptr = head;

  while(ptr!=null){
    if(c.compare(obj, ptr.data)==0){ // ๊ฒ€์ƒ‰ ์„ฑ๊ณต
      crnt = ptr;
      return ptr.data;
    }
    ptr = ptr.next;                  // ๋‹ค์Œ ๋…ธ๋“œ ์„ ํƒ
  }
  return null;                       // ๊ฒ€์ƒ‰ ์‹คํŒจ
}

2) ๋ฐ์ดํ„ฐ ์‚ฝ์ž…

๋จธ๋ฆฌ์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…

์‚ฝ์ž… ์ „์˜ ๋จธ๋ฆฌ ๋…ธ๋“œ(A)์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ptr์— ๋Œ€์ž…ํ•˜๊ณ 
์‚ฝ์ž… ๋  ์ƒˆ๋กœ์šด ๋…ธ๋“œ(F)๋ฅผ ์ƒ์„ฑ, ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋Š” obj, ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์€ ptr์ด ๋œ๋‹ค.
์ƒ์„ฑํ•œ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก head๋ฅผ ์—…๋ฐ์ดํŠธ

๊ผฌ๋ฆฌ์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…

๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ์•„๋‹Œ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ  ์ž‘์—…์„ ์ˆ˜ํ–‰

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ

    ๋จธ๋ฆฌ์— ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž… ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผ

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ

    ๋ฆฌ์ŠคํŠธ ๊ผฌ๋ฆฌ์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…

์ฝ”๋“œ

//๋จธ๋ฆฌ์— ๋…ธ๋“œ ์‚ฝ์ž…
public void addFirst(E obj){
  Node<E> ptr = head;
  head = crnt = new Node<E>(obj, ptr);
}

//๊ผฌ๋ฆฌ์— ๋…ธ๋“œ ์‚ฝ์ž…
public void addLast(E obj){
  if(head == null)
    addFirst(obj);
  else{
    Node<E> ptr = head;
    while(ptr.next!=null)   // while๋ฌธ ์ข…๋ฃŒ์‹œ ptr์€ ๊ผฌ๋ฆฌ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
      ptr = ptr.next;
    ptr.next = crnt = new Node<E>(obj, null);
  }
}

3) ๋ฐ์ดํ„ฐ ์‚ญ์ œ

- ๋จธ๋ฆฌ ๋…ธ๋“œ ์‚ญ์ œ

๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ๊ฐ€ ํ•œ๊ฐœ๋งŒ ์žˆ์–ด๋„ ์˜ค๋ฅ˜์—†์ด ์‚ญ์ œ ๊ฐ€๋Šฅ

- ๊ผฌ๋ฆฌ ๋…ธ๋“œ ์‚ญ์ œ

๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ๊ฐ€ ๋ช‡๊ฐœ ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰

  • ๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ

    ๋จธ๋ฆฌ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ์ž‘์—…๊ณผ ๊ฐ™์Œ

  • ๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ๊ฐ€ 2๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ

    ๊ผฌ๋ฆฌ ๋…ธ๋“œ์™€ ๊ผฌ๋ฆฌ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๋‘๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š”๋‹ค.
    ๊ผฌ๋ฆฌ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๋‘๋ฒˆ์งธ ๋…ธ๋“œ์˜ ๋’ค์ชฝ ํฌ์ธํ„ฐ์— null์„ ๋Œ€์ž…
    ์–ด๋””์—๋„ ์ฐธ์กฐ๋˜์ง€ ์•Š์„ ๊ผฌ๋ฆฌ๋…ธ๋“œ๋Š” ์ž๋™์œผ๋กœ ํ•ด์ง€ ๋  ๊ฒƒ

์ฝ”๋“œ

//๋จธ๋ฆฌ ๋…ธ๋“œ ์‚ญ์ œ
public void removeFirst(){
  if(head!=null)
    head = crnt = head.next;
}

//๊ผฌ๋ฆฌ ๋…ธ๋“œ ์‚ญ์ œ
public void removeLast(){
  if(head!=null){
    if(head.next==null)
      removeFirst();
  }
  else{
      Node<E> ptr = head;   // ์Šค์บ” ์ค‘์ธ ๋…ธ๋“œ
      Node<E> pre = head;   // ์Šค์บ” ์ค‘์ธ ๋…ธ๋“œ์˜ ์•ž์ชฝ ๋…ธ๋“œ

      while(ptr.next!=null){
        pre = ptr;
        ptr = ptr.next;
      }
      pre.next = null;    // pre๋Š” ์‚ญ์ œ ์ž‘์—… ํ›„์˜ ๊ผฌ๋ฆฌ ๋…ธ๋“œ
      crnt = pre;
  }
}

- ์„ ํƒํ•œ ๋…ธ๋“œ ์‚ญ์ œ

์„ ํƒํ•œ ๋…ธ๋“œ๊ฐ€ ๋จธ๋ฆฌ ๋…ธ๋“œ์ธ์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ ์ž‘์—…์„ ์ˆ˜ํ–‰

  • p๊ฐ€ ๋จธ๋ฆฌ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ

    ๋จธ๋ฆฌ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ

  • p๊ฐ€ ๋จธ๋ฆฌ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ

    p์˜ ์•ž์ชฝ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š”๋‹ค. (ptr์ด ์ฐธ์กฐํ•˜๊ฒŒ ๋จ)
    p์˜ ๋’ค์ชฝ ํฌ์ธํ„ฐ p.next๋ฅผ ptr์˜ ptr.next์— ๋Œ€์ž…
    ptr์˜ ๋’ค์ชฝ ํฌ์ธํ„ฐ๊ฐ€ p์˜ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
    ์–ด๋””์—๋„ ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ๋…ธ๋“œ p์˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ž๋™์œผ๋กœ ํ•ด์ง€๋œ๋‹ค.

(p๋Š” ์‚ญ์ œ๋˜๊ธฐ ์œ„ํ•ด ์„ ํƒ๋œ ๋…ธ๋“œ์ด๋‹ค.)

์ฝ”๋“œ

//๋…ธ๋“œ p ์‚ญ์ œ
public void remove(Node p){
  if(head!=null){
    if(p==head)
      removeFirst();
  }
  else{
    Node<E> ptr = head;

    while(ptr.next!=p){
      ptr = ptr.next;
      if(ptr==null) return;   // p๊ฐ€ ๋ฆฌ์ŠคํŠธ์— ์—†์Œ
    }
    ptr.next = p.next;
    crnt = ptr;
  }
}

//์„ ํƒ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ
public void removeCurrentNode(){
  remove(crnt);
}

//๋ชจ๋“  ๋…ธ๋“œ ์‚ญ์ œ
public void clear(){
  while(head!=null)   //๋…ธ๋“œ์— ์•„๋ฌด๊ฒƒ๋„ ์—†์„ ๋•Œ ๊นŒ์ง€ ๋จธ๋ฆฌ๋…ธ๋“œ๋ฅผ ์‚ญ์ œ
    removeFirst();
  crnt = null;
}

3. ์›ํ˜• ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

3-1. ์›ํ˜• ๋ฆฌ์ŠคํŠธ

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ผฌ๋ฆฌ ๋…ธ๋“œ๊ฐ€ ๋จธ๋ฆฌ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ตฌ์กฐ์˜ ๋ฆฌ์ŠคํŠธ
๊ณ ๋ฆฌ ๋ชจ์–‘์œผ๋กœ ๋‚˜์—ด๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ์•Œ๋งž์€ ์ž๋ฃŒ๊ตฌ์กฐ

3-2. ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ€์žฅ ํฐ ๋‹จ์ ์€ ๋‹ค์Œ ๋…ธ๋“œ๋Š” ์ฐพ๊ธฐ ์‰ฝ์ง€๋งŒ ์•ž์ชฝ์˜ ๋…ธ๋“œ๋Š” ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์  ์ด๋‹ค.
์ด ๋‹จ์ ์„ ๊ฐœ์„ ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์ด๋‹ค.

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋Š” ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ ๊ณต๊ฐ„์ด ์žˆ๋‹ค.
๊ฐ๊ฐ์˜ ํฌ์ธํ„ฐ๋Š” ์•ž์˜ ๋…ธ๋“œ์™€ ๋’ค์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

class Node<E>{
  E data;
  Node<E> prev; // ๋จธ๋ฆฌ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
  Node<E> next; // ๊ผฌ๋ฆฌ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
}

3-3. ์›ํ˜• ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

์›ํ˜• ๋ฆฌ์ŠคํŠธ์™€ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐœ๋…์ด ํ•ฉํ•ด์ง„ ๊ตฌ์กฐ์˜ ๋ฆฌ์ŠคํŠธ์ด๋‹ค.


Reference & Additional Resources

  • Do it! ์ž๋ฃŒ๊ตฌ์กฐ์™€ ํ•จ๊ป˜ ๋ฐฐ์šฐ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž…๋ฌธ
    ( ์ฑ…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

  • ์ด๋ฏธ์ง€ - ์ง์ ‘ ์ œ์ž‘