[Data Structure] LinkedList
LinkedList
1. LinkedList란?
LinkedList는 ArrayList와 다르게 요소와 요소 사이를 링크로 연결한 리스트이다.
둘 다 크기에 제한은 없지만 기능의 차이가 있다.
ArrayList는 배열을 기반으로 만들어진 리스트이기 때문에 정해져있는 배열이 꽉 차면 그 배열의 2배크기의 배열을 새로 만들어서 데이터를 옮긴다.
LinkedList는 요소 사이를 링크로 이어주기만 하면 되기 때문에 크기에 제한이 없다.
하지만 검색을 하는 경우 각 요소가 다음 요소만을 알고 있기 때문에 모든 요소를 훑어 올라가야한다.
마지막 요소를 검색해야 하는 경우 첫번째 요소부터 마지막 요소까지 봐야하기 때문에 이 경우가 최악의 경우이다.
그러므로 검색이 별로 없고 추가/삭제를 많이 하는 경우 사용하면 좋다.
(출처: 생활코딩)
2. LinkedList 기능
2.1 데이터의 추가
(출처: 생활코딩)
ArrayList와 LinkedList의 핵심적인 차이는 여기에서 드러난다.
배열은 요소를 중간에 추가/삭제하면 그 요소 뒤의 요소들을 한칸씩 이동해야했다. 그래서 ArrayList는 추가/삭제가 많은 경우에 맞지 않는다.
하지만 LinkedList는 추가/삭제가 될 요소의 이전 요소 next(참조 주소값)를 바꾸면 되기 때문에 속도가 빠르다.
JavaScript로 데이터 추가에 대한 구현은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var LinkedList = function() {
this.length = 0; // 요소 개수 체크
this.head = null; // 첫번째 요소의 참조 주소값 저장
};
var Node = function(elem) {
this.data = elem;
this.next = null;
};
LinkedList.prototype.addFirst = function(elem) {
return this.add(0, elem);
};
LinkedList.prototype.add = function(index, elem) {
var node = new Node(elem);
var curr = this.head;
var prev;
var i = 0;
if (index >= 0 && index <= this.length) {
if (index === 0) {
node.next = curr;
this.head = node;
} else {
while (i++ < index) {
prev = curr;
curr = curr.next;
}
node.next = curr;
prev.next = node;
}
this.length++;
return LinkedList;
}
return false;
};
LinkedList.prototype.addLast = function(elem) {
return this.add(this.length, elem);
};
2.2 데이터의 삭제
(출처: 생활코딩)
삭제할 요소의 이전 노드가 삭제요소의 다음 노드를 가리키게 하면 삭제할 요소의 주소값을 가진 요소가 없기 때문에 없는 요소나 다름 없다.
즉, 삭제할 요소 외에 다른 요소들을 모두 연결해주면 삭제할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 첫번째 요소 삭제
LinkedList.prototype.removeFirst = function() {
return this.remove(0);
};
// 요소 삭제
LinkedList.prototype.remove = function(index) {
var curr = this.head;
var prev;
var i = 0;
if (index === 0) {
this.head = curr.next;
} else {
while (i++ < index) {
prev = curr;
curr = prev.next;
}
prev.next = curr.next;
}
curr.next = null;
this.length--;
return curr.data;
};
// 마지막 요소 삭제
LinkedList.prototype.removeLast = function() {
return this.remove(this.length - 1);
};
2.3 데이터 검색
(출처: 생활코딩)
LinkedList는 자신과 다음 요소밖에 모르기때문에 위의 그림과 같이 마지막 요소를 검색하려면 처음부터 마지막까지 찾아야한다.
데이터 양이 많고 조회가 많은 경우엔 ArrayList에 비해 시간이 오래 걸린다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 데이터 검색
LinkedList.prototype.indexOf = function(elem) {
var temp = this.head; // 첫번째 요소 지정
var index = 0;
while (temp.data != elem) {
temp = temp.next;
index++;
if (temp === null) {
// temp가 null인 것은 temp의 이전 요소가 마지막 요소라는 뜻.
return -1;
}
}
return index;
};
2.4 데이터 reverse
</br>
데이터를 반전시키는 기능이다. next의 주소값을 이전 요소로 바꿔주면 된다.
기존 요소를 저장해놓고 참조 주소값를 반대로 변경해주고 다시 기존의 주소를 넣어주는 반복을 행하면 reverse 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
// 요소 찾기
LinkedList.prototype.reverse = function() {
var curr = this.head;
var next = null,
prev = null;
while (curr) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
this.head = prev;
};