written by sohyeon, hyemin ๐ก
๋จผ์ , ๋ฆฌ์คํธ
๋ ๋ฐ์ดํฐ๋ฅผ ์์๋๋ก ๋์ดํ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์์ ๊ทธ๋ฆผ ์ฒ๋ผ ์์๊ฐ ์์ผ๋ฉฐ ๊ฐ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋์ด๋์ด ์๋ ํํ์ด๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ
๋ ๋์ด๋ ๋ถ์ฐ์์ ์ธ ๋ฐ์ดํฐ๋ฅผ ์๋ก ์ฐ๊ฒฐํ ํํ์ด๋ค.
๊ฐ ๋
ธ๋๊ฐ ๋ฐ์ดํฐ์ ํฌ์ธํฐ๋ฅผ ๊ฐ์ง๊ณ ํ ์ค๋ก ์ฐ๊ฒฐ๋์ด ์๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์๋ค.
์ด๋ ๋ฆฌ์คํธ์ ๋ฐ์ดํฐ๋ ๋
ธ๋ ๋๋ ์์๋ผ๊ณ ํ๋ค.
๊ฐ๊ฐ์ ๋
ธ๋๋ ๋ฐ์ดํฐ์ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. (์์ ๊ทธ๋ฆผ์์ ํ์ ์ )
ํ๋์ ๋
ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฐ๋ก ์์ ์๋ ๋
ธ๋๋ฅผ ์์ชฝ ๋
ธ๋(predecessor node)
, ๋ฐ๋ก ๋ค์ ์๋ ๋
ธ๋๋ฅผ ๋ค์ ๋
ธ๋(successor node)
๋ผ๊ณ ํ๋ค.
< ๋ฐฐ์ด์ ๋จ์ >
- ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
- ๋น์์ฐจ์ ์ธ ๋ฐ์ดํฐ์ ์ถ๊ฐ, ์ญ์ ์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฐ๋ค.
(๋ฐฐ์ด ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ๋น์๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋ฐ์ดํฐ ๋ณต์ฌ, ์ด๋ ๊ณผ์ ์ด ํ์ํ๋ค.)
-> ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ ์ด๋ฌํ ๋ฐฐ์ด์ ๋จ์ ์ ๋ณด์ํ๋ค.
๋ฐฐ์ด์ฒ๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌ, ์ด๋ํ๋ ๊ณผ์ ์์ด ๋
ธ๋ ๊ฐ์ ์ฐธ์กฐ ๋ณ๊ฒฝ๋ง์ผ๋ก ๋ฐ์ดํฐ ์ถ๊ฐ, ์ญ์ ๊ฐ ๊ฐ๋ฅํ๋ค.
ํฌ์ธํฐ๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ธฐ์ค์ผ๋ก ์์ฑํ๊ฒ ์ต๋๋ค.
๋ ธ๋ ๊ฐ์ฒด์๋ ๋ฐ์ดํฐ์ ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๊ฐ ์กด์ฌํ๋ค.
class Node<E>{
E data; // ๋ฐ์ดํฐ
Node<E> next; // ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ
}
next
๋ ์๊ธฐ ์์ ๊ณผ ๊ฐ์ ํด๋์คํ์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํ ์ฐธ์กฐํ ํ๋์ด๋ค.
Node๋ ์ ๋ค๋ฆญ์ผ๋ก ๊ตฌํ๋๋ฏ๋ก ๋ฐ์ดํฐ ํ E๋ ์์์ ํด๋์คํ์ด ํ์ฉ๋๋ค.
ํ๋ dataํ์ธ E๋ ์ฐธ์กฐํ์ด๋ผ๋ ๊ฒ์ ์ ์ํ์.
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
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; // ๊ฒ์ ์คํจ
}
์ฝ์
์ ์ ๋จธ๋ฆฌ ๋
ธ๋(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);
}
}
๋ฆฌ์คํธ์ ๋ ธ๋๊ฐ ํ๊ฐ๋ง ์์ด๋ ์ค๋ฅ์์ด ์ญ์ ๊ฐ๋ฅ
๋ฆฌ์คํธ์ ๋ ธ๋๊ฐ ๋ช๊ฐ ์๋์ง์ ๋ฐ๋ผ ํด๋น ์์ ์ ์ํ
-
๋ฆฌ์คํธ์ ๋ ธ๋๊ฐ 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;
}
์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ผฌ๋ฆฌ ๋
ธ๋๊ฐ ๋จธ๋ฆฌ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ตฌ์กฐ์ ๋ฆฌ์คํธ
๊ณ ๋ฆฌ ๋ชจ์์ผ๋ก ๋์ด๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ ์๋ง์ ์๋ฃ๊ตฌ์กฐ
์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ฐ์ฅ ํฐ ๋จ์ ์ ๋ค์ ๋
ธ๋๋ ์ฐพ๊ธฐ ์ฝ์ง๋ง ์์ชฝ์ ๋
ธ๋๋ ์ฐพ์ ์ ์๋ค๋ ์ ์ด๋ค.
์ด ๋จ์ ์ ๊ฐ์ ํ ์๋ฃ๊ตฌ์กฐ๊ฐ ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ
์ด๋ค.
์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ
์ ๋
ธ๋๋ ๋ ๊ฐ์ ํฌ์ธํฐ ๊ณต๊ฐ์ด ์๋ค.
๊ฐ๊ฐ์ ํฌ์ธํฐ๋ ์์ ๋
ธ๋์ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
class Node<E>{
E data;
Node<E> prev; // ๋จธ๋ฆฌ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํด
Node<E> next; // ๊ผฌ๋ฆฌ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํด
}
์ํ ๋ฆฌ์คํธ์ ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ฐ๋ ์ด ํฉํด์ง ๊ตฌ์กฐ์ ๋ฆฌ์คํธ์ด๋ค.
-
Do it! ์๋ฃ๊ตฌ์กฐ์ ํจ๊ป ๋ฐฐ์ฐ๋ ์๊ณ ๋ฆฌ์ฆ ์ ๋ฌธ
( ์ฑ ์ ๊ธฐ๋ฐ์ผ๋ก ๊ณต๋ถํ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ฒ์ ๋๋ค.) -
์ด๋ฏธ์ง - ์ง์ ์ ์