์์
Linked list(๋งํฌ๋ ๋ฆฌ์คํธ) ๋?
ใด Linked list์ List์ ์ฐจ์ด์
ใด Single Linked List์ Doubly Linked List ์ฐจ์ด์ (Doubly Linked List๊ฐ ํ์ํ ์ด์ )
Single Linked list ๊ตฌํ(JAVA)
Doubly Linked list ๊ตฌํ(JAVA)
๐ค Linked list ๋ ๋ฌด์์ธ๊ฐ?
List์์ ์ฐจ์ด์
์ฐ๊ฒฐ๋ ๋ฆฌ์คํธ๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ ๋งํฌ๋ ๋ฆฌ์คํธ๋ ์ผ๋ฐ ๋ฆฌ์คํธ(List)์ ์ฐจ์ด์ ์ ๋ณด๋ฉด์ ์ด์ผ๊ธฐํ ์ ์๋ค.
๊ธฐ๋ณธ์ ์ธ List๋ ์์ฐจ์ ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๋ฐฐ์ด ๊ตฌ์กฐ์ด๋ค.
List ๊ตฌ์กฐ
index(์์) | 0 | 1 | 2 | 3 | 4 | 5 |
value(๊ฐ) | "์ฒซ๋ฒ์งธ ๊ฐ" | "๋๋ฒ์งธ ๊ฐ" | "์ธ๋ฒ์งธ ๊ฐ" | "๋ค๋ฒ์งธ ๊ฐ" | "๋ค์ฏ๋ฒ์งธ ๊ฐ" | "์ฌ์ฏ๋ฒ์งธ ๊ฐ" |
์ ํ์ ๊ฐ์ List๊ฐ ์ ์ฅ๋์ด์๋ค๋ฉด ํด๋น ๋ฆฌ์คํธ๋ ["์ฒซ๋ฒ์งธ ๊ฐ", "๋๋ฒ์งธ ๊ฐ", "์ธ๋ฒ์งธ ๊ฐ", "๋ค๋ฒ์งธ ๊ฐ" ...] ์ ๊ฐ์ด ์์ฐจ์ ์ผ๋ก ๊ฐ์ ๊ฐ๋ ๊ฒ์ด๋ค. (์์๋๋ก ๋น์ด์๋ ๊ณต๊ฐ์ ์ ์ฅ)
ํ์ง๋ง, ์ผ๋ฐ์ ์ธ List์ ๊ฒฝ์ฐ ์ ์ธํ ๋น์์ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์ ํด์ค์ผํ๋ค.
ex) String[] list = String[6]; => ํฌ๊ธฐ๊ฐ 6์ธ ๋ฌธ์์ด ๋ฐฐ์ด
๊ทธ๋ ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ๋ ๋ญ๋นํ์ง ์๊ธฐ ์ํด์ ํ์ํ ํฌ๊ธฐ๋งํผ๋ง ์ ์ํด์ ์ฌ์ฉํ๋๊ฒ ํจ์จ์ ์ธ๋ฐ ๋ง์ผ, ๊ฐ๋ณ์ ์ผ๋ก ํฌ๊ธฐ๊ฐ ๋ณํด์ผํ๋ ์ํฉ์ด๋ผ๋ฉด, ์ด ์ฒ๋ผ List๋ฅผ ์ฌ์ฉํ๋๊ฒ ์ฝ์ง ์๋ค.
Linked List๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ฏธ๋ฆฌ ์ ํด์ฃผ์ง ์๊ณ ํ์ํ ๋ ๋ง๋ค ๋ ธ๋(node)๋ฅผ ์ถ๊ฐํ๊ณ ์ฐ๊ฒฐํด ์ค์ผ๋ก์ ๊ฐ๋ณ์ ์ธ ์ํฉ์ ๋์ฒํ ์ ์๋ค.
์ฌ๊ธฐ์ ๋ ธ๋๋, ํ๋์ ๊ฐ(value)๋ฅผ ๊ฐ๊ณ ์๋ ๊ณต๊ฐ์ ์๋ฏธํ๋ค. ์์ List ํ ์ด๋ธ์์ ํ ์นธ์ ํ๋์ value๋ฅผ ๊ฐ๋๋ฐ ์ด ๊ณต๊ฐ์ ๋ ธ๋๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
Linked List์ ๋ชจ์ต์ ๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
Single Linked List
node ์์๋ ๋ฐ์ดํฐ ๊ฐ์ธ value์ ๋ค๋ฅธ node์ ์์น ์ ๋ณด(์ปดํจํฐ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์)๋ฅผ ๊ฐ์ง๋ค.
ํ๋์ node๋ฅผ ์๋ฉด ๋ค๋ฅธ node๋ค์ ๋ชจ๋ ์ฐพ์๊ฐ ์ ์๋ค. ์ถ๊ฐ์ ์ธ data๋ฅผ ์ ์ฅํ ํ์๊ฐ ์์ ๋ node๋ฅผ ์์ฑํ๊ณ ๋งจ ๋ pointer์ ์๋ก์ด Node์ ์์น๋ฅผ ์ ์ฅํ๋ฉด ์ฐ๊ฒฐ๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
์ด๋ ๊ฒ ํ๋์ ๋ ธ๋๊ฐ ๋ฐ์ดํฐ ๊ฐ๊ณผ ๋ค๋ฅธ ๋ ธ๋์ ์์น ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉด Linked List๋ผ๊ณ ํ ์ ์๋ค.
์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ํ๋์ pointer(๋ค์ ์์์ node ์์น ์ ๋ณด)๋ฅผ ๊ฐ์ง๋ฉด Single Linked List๋ผ๊ณ ํ๋ค.
์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด pointer๊ฐ 2๊ฐ ์กด์ฌํด ์ด์ node์ ์์น ์ ๋ณด์ ๋ค์ node์ ์์น ์ ๋ณด๋ฅผ ๋ชจ๋ ๊ฐ์ง๊ณ ์๋ node๋ค์ด ์๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๋ฉด Doubly Linked List๋ผ๊ณ ํ๋ค.
๊ทธ๋ผ Doubly Linked List๋ ์ ํ์ํ ๊น?
Single Linked List์ ๊ฒฝ์ฐ pointer๊ฐ ์์ ์ ๋ค์ node๋ง์ ๊ฐ๋ฅดํค๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๊ฐ์ ์กฐํ, ์ฝ์ , ์ญ์ ํ๊ธฐ ์ํด์๋ ๊ธฐ์ค์ด ๋ ์ ์๋ ์ ์ผ ์์ node (์ฌ๊ธฐ์ head)๋ฅผ ์์์ผ ํ๋ค.
ํน์ node๋ฅผ ์ฐพ๊ธฐ ์ํด์๋ head๋ฅผ ์์์ผ๋ก ์ฐพ์ data์ ์ผ์นํ๋์ง ํ์ธํ๊ณ ์๋ ๊ฒฝ์ฐ head์ pointer์์ ๋ค์ node์ ์์น๋ฅผ ํ์ธํ๊ณ ์ด๋ํด ๋ค์ data๊ฐ ์ผ์นํ๋์ง ํ์ธํ๋ ๊ฒ์ ๋ฐ๋ณตํด์ผ ํ๋ค.
๋ง์ฝ์ ์ฐพ์์ผํ ๊ฐ์ด node์ ๋๋ถ๋ถ์ ์์๋ค๋ฉด ์๋นํ ๋นํจ์จ์ ์ด๊ฒ ๋๋ค. ์ฐพ์์ผํ ๋ฐ์ดํฐ๊ฐ ์์์์์ง ๋ค์ ์์์ง ์์ธกํ ์ ์๋ค๋ฉด, ์์ชฝ์์ ๋ชจ๋ ์์ํ ์ ์๋ ๊ฒ์ด ํจ์จ์ ์ผ ๊ฒ์ด๋ค.
์ด๋ ์ฌ์ฉ๊ฐ๋ฅํ ๊ฒ์ด doubly Linked List์ด๋ค.
Doubly Linked List์ ๊ฒฝ์ฐ, pointer๋ก ์์ node์ ๋ค์ node๋ฅผ ๋ชจ๋ ํ์ธํ ์ ์์ด์ ์ํฉ์ ๋ง๊ฒ ๋ค์์ ํ์์ํ ๊ฒ์ธ์ง ๋งจ ์์์ ํ์์ํ ๊ฒ์ธ์ง ๊ฒฐ์ ํ ์ ์๋ค.
๐ Single Linked List ๊ตฌํํ๊ธฐ for Java
public class SingleLinkedList<T> {
// ๊ธฐ์ค์ด ๋๋ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ node
public Node<T> head = null;
// ๋ด์ฅ ๊ฐ์ฒด Node ์ ์
public class Node<T> {
T data;
Node<T> next = null;
// Node class์ ์์ฑ์
public Node(T data) {
this.data = data;
}
}
// ๋งจ ๋ ๋จ์ ๋
ธ๋ ์ถ๊ฐ
public void addNode(T newData) {
if(head == null) { // List๋ ๋น์ด์๋ ์ํ
head = new Node<>(newData);
}
else { // ๋น์ด์์ง ์๋ค๋ฉด ๊ฐ์ฅ ๋ node๋ฅผ ํ์
// head ๋ก ์ด๋
Node<T> node = this.head;
// node์ next๊ฐ null ์ผ ๋ ๊น์ง
while (node.next != null) {
node = node.next;
}
// ๋ค์ ๋งํฌ๋ฅผ ์ฐ๊ฒฐ
node.next = new Node<T>(newData);
}
}
// ๋
ธ๋ ์ค๊ฐ ์ถ๊ฐ
public void insertNode(T data, T where){ // data: ์ฝ์
ํ ๋ฐ์ดํฐ, where: ์ฝ์
ํ ๋ฐ์ดํฐ์ ๊ธฐ์ค ์์น
Node<T> searchNode = this.search(where);
if (searchNode == null) {
this.addNode(data);
} else {
Node<T> nextNode = searchNode.next;
searchNode.next = new Node<>(data); // ๊ธฐ์ค์ ๋ค์ ์ฝ์
searchNode.next.next = nextNode; // ์๋ก ์ฝ์
ํ ๋ฐ์ดํฐ์ ๊ธฐ์ค์ ์ ๊ธฐ์กด next๋ฅผ ์ฝ์
}
}
// node ๊ฒ์
public Node<T> search(T where) {
if (this.head == null) {
return null;
} else {
Node<T> node = head;
while(node.next != null) {
if(node.data == where){
return node;
} else {
node = node.next;
}
}
// ๋ชจ๋ ํ์ ํ ์๋ค๋ฉด null ๋ฆฌํด
return null;
}
}
// node ์ญ์ ๋ฉ์๋
public boolean delNode(T data) {
if(this.head == null) {
return false;
} else {
Node<T> node = this.head;
if(node.data == data) {
this.head = this.head.next;
return true;
} else {
// node ์ด๋
while(node.next != null) {
if(node.next.data == data) {
node.next = node.next.next;
return true;
} else {
node = node.next;
}
// ๋ชจ๋ ํ์์ ๋ง์น ํ ์์ผ๋ฉด false;
}
return false;
}
}
}
}
๐ Doubly Linked List ๊ตฌํํ๊ธฐ for Java
public class DoublyLinkedList<T> {
public Node<T> head; // ๊ฐ์ฅ ์์ node
public Node<T> tail; // ๊ฐ์ฅ ๋ค์ node
// ๋ด์ฅ ๊ฐ์ฒด node
public class Node<T>{
T data;
Node<T> prev; // ์ node์ pointer
Node<T> next; // ๋ค node์ pointer
public Node(T data) { // ์์ฑ์
this.data = data;
}
}
// ๋งจ ๋์ node ์ถ๊ฐํ๊ธฐ
public void addNode(T data) {
if(this.head == null){
this.head = new Node<>(data);
this.tail = this.head;
} else {
Node<T> node = head;
while(node.next != null){
node = node.next;
}
node.next = new Node<>(data);
node.next.prev = node;
this.tail = node.next;
}
}
// head์์ ํน์ ๊ฐ ์ฐพ๊ธฐ
public T findFromHead(T data) {
if(this.head != null) {
Node<T> node = head;
while(node != null) {
if(node.data == data) {
return node.data;
} else {
node = node.next;
}
}
return null;
}
return null;
}
// ๋งจ ๋ค node์์ ํน์ ๊ฐ ์ฐพ๊ธฐ
public T findFromTail(T data) {
if(this.tail != null) {
Node<T> node = this.tail;
while(node != null) {
if(node.data == data){
return node.data;
} else {
node = node.prev;
}
}
return null;
}
return null;
}
// param์ ๊ฐ์ ๊ฐ์ง๋ Node์ node ์ถ๊ฐํ๊ธฐ(head ์์๋ถํฐ ์ฐพ๊ธฐ)
public boolean addNodeToFront(T addData, T targetData){
if(this.head == null) {
this.head = new Node<>(addData);
this.tail = this.head;
return true;
} else if(this.head.data == targetData) {
Node<T> newHead = new Node<>(addData);
newHead.next = this.head;
this.head = newHead;
this.head.next.prev = this.head;
return true;
} else {
Node<T> node = this.head;
while (node != null) {
if(node.data == targetData){
Node<T> addNode = new Node<>(addData);
addNode.prev = node.prev;
addNode.next = node;
node.prev.next = addNode;
node.prev = addNode;
return true;
} else{
node = node.next;
}
}
return false;
}
}
}