- 링크드 리스트 구조
- 연결 리스트
- 떨어진 곳에 존재하는 데이터를 화살표로 연결해서 관리하는 데이터 구조
- 배열의 미리 공간을 지정해야 하는 단점을 극복한 자료구조
- 링크드 리스트 기본 구조와 용어
- 노드(Node): 데이터 저장 단위(데이터값, 포인터)로 구성
- 포인터(Pointer): 각 노드 안에서, 다음이나 이전의 노드와의 연결 정보를 가지고 있는 공간
단일 연결 리스트( 출처: https://en.wikipedia.org/wiki/Linked_list )
- Linked List 장단점
- 장점
- 단점
- 연결을 위한 별도 데이터 공간이 필요하므로 저장공간 효율이 높지 않음
- 연결 정보를 찾는 시간이 필요하므로 접근 속도가 느림
- 중간 데이터 삭제 시, 앞뒤 데이터의 연결을 재구성해야 하는 부가적인 작업 필요
- 자바스크립트로 Linked List 구현
const LinkedList = (function() {
function LinkedList() {
this.head = null;
}
function Node(data, next=null) {
this.data = data;
this.next = next;
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
}
function Node(data, next=null) {
this.data = data;
this.next = next;
}
LinkedList.prototype.add = function(data) {
let node = new Node(data);
let curNode = this.head;
if( !curNode ) {
this.head = node;
} else {
while(curNode.next) {
curNode = curNode.next;
}
curNode.next = node;
}
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
}
function Node(data, next=null) {
this.data = data;
this.next = next;
}
LinkedList.prototype.remove = function(data) {
let curNode = this.head;
if( !curNode ) return;
if( curNode.data === data ) {
this.head = this.head.next;
} else {
while(curNode.next) {
if( curNode.next.data === data ) {
curNode.next = curNode.next.next || null;
break;
}
curNode = curNode.next;
}
}
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
}
function Node(data, next=null) {
this.data = data;
this.next = next;
}
LinkedList.prototype.add = function(data) {
let node = new Node(data);
let curNode = this.head;
if( !curNode ) {
this.head = node;
} else {
while(curNode.next) {
curNode = curNode.next;
}
curNode.next = node;
}
}
LinkedList.prototype.remove = function(data) {
let curNode = this.head;
if( !curNode ) return;
if( curNode.data === data ) {
this.head = this.head.next;
} else {
while(curNode.next) {
if( curNode.next.data === data ) {
curNode.next = curNode.next.next || null;
break;
}
curNode = curNode.next;
}
}
}
LinkedList.prototype.search = function(data) {
let curNode = this.head;
while(curNode) {
if( curNode.data === data ) {
return curNode;
}
curNode = curNode.next;
}
return false;
}
LinkedList.prototype.print = function() {
let node = this.head;
while(node) {
console.log(node.data);
node = node.next;
}
}
return LinkedList;
})();
const linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
linkedList.add(4);
linkedList.add(5);
linkedList.remove(3);
linkedList.remove(1);
linkedList.print();
- 더블 링크드 리스트(Double Linked List)
- 이중 연결 리스트
- 양방향으로 연결되어 있어서 노드 탐색이 양쪽으로 가능
이중 연결 리스트( 출처: https://en.wikipedia.org/wiki/Linked_list )
- Linked List, Node 구현
- Linked List에 tail property 추가
- Node에 prev property 추가
const LinkedList = (function() {
function LinkedList() {
this.head = null;
this.tail = null;
}
function Node(data, prev=null, next=null) {
this.data = data;
this.prev = prev;
this.next = next;
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
this.tail = null;
}
function Node(data, prev=null, next=null) {
this.data = data;
this.prev = prev;
this.next = next;
}
LinkedList.prototype.add = function(data) {
let node = new Node(data);
let curNode = this.head;
this.tail = node;
if( !curNode ) {
this.head = node;
} else {
while(curNode.next) {
curNode = curNode.next;
}
curNode.next = node;
node.prev = curNode;
}
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
this.tail = null;
}
function Node(data, prev=null, next=null) {
this.data = data;
this.prev = prev;
this.next = next;
}
LinkedList.prototype.insert_before = function(data, before_data) {
let node = new Node(data);
if( !this.head ) {
this.head = node;
this.tail = node;
return true;
} else {
let curNode = this.tail;
while(curNode.data !== before_data) {
curNode = curNode.prev;
if( !curNode ) return false;
}
let beforeNode = curNode.prev;
beforeNode.next = node;
curNode.prev = node;
node.prev = beforeNode;
node.next = curNode;
return true;
}
}
LinkedList.prototype.insert_after = function(data, after_data) {
let node = new Node(data);
if( !this.head ) {
this.head = node;
this.tail = node;
return true;
} else {
let curNode = this.head;
while(curNode.data !== after_data) {
curNode = curNode.next;
if( !curNode ) return false;
}
let afterNode = curNode.next;
afterNode.prev = node;
curNode.next = node;
node.prev = curNode;
node.next = afterNode;
return true;
}
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
this.tail = null;
}
function Node(data, prev=null, next=null) {
this.data = data;
this.prev = prev;
this.next = next;
}
LinkedList.prototype.search_from_head = function(data) {
let curNode = this.head;
while(curNode) {
if( curNode.data === data ) {
return curNode;
}
curNode = curNode.next;
}
return false;
}
LinkedList.prototype.search_from_tail = function(data) {
let curNode = this.tail;
while(curNode) {
if( curNode.data === data ) {
return curNode;
}
curNode = curNode.prev;
}
return false;
}
return LinkedList;
})();
const LinkedList = (function() {
function LinkedList() {
this.head = null;
this.tail = null;
}
function Node(data, prev=null, next=null) {
this.data = data;
this.prev = prev;
this.next = next;
}
LinkedList.prototype.add = function(data) {
let node = new Node(data);
let curNode = this.head;
this.tail = node;
if( !curNode ) {
this.head = node;
} else {
while(curNode.next) {
curNode = curNode.next;
}
curNode.next = node;
node.prev = curNode;
}
}
LinkedList.prototype.search_from_head = function(data) {
let curNode = this.head;
while(curNode) {
if( curNode.data === data ) {
return curNode;
}
curNode = curNode.next;
}
return false;
}
LinkedList.prototype.search_from_tail = function(data) {
let curNode = this.tail;
while(curNode) {
if( curNode.data === data ) {
return curNode;
}
curNode = curNode.prev;
}
return false;
}
LinkedList.prototype.insert_before = function(data, before_data) {
let node = new Node(data);
if( !this.head ) {
this.head = node;
this.tail = node;
return true;
} else {
let curNode = this.tail;
while(curNode.data !== before_data) {
curNode = curNode.prev;
if( !curNode ) return false;
}
let beforeNode = curNode.prev;
beforeNode.next = node;
curNode.prev = node;
node.prev = beforeNode;
node.next = curNode;
return true;
}
}
LinkedList.prototype.insert_after = function(data, after_data) {
let node = new Node(data);
if( !this.head ) {
this.head = node;
this.tail = node;
return true;
} else {
let curNode = this.head;
while(curNode.data !== after_data) {
curNode = curNode.next;
if( !curNode ) return false;
}
let afterNode = curNode.next;
afterNode.prev = node;
curNode.next = node;
node.prev = curNode;
node.next = afterNode;
return true;
}
}
LinkedList.prototype.print = function() {
let node = this.head;
while(node) {
console.log(node.data);
node = node.next;
}
}
return LinkedList;
})();
const linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
linkedList.add(4);
linkedList.add(5);
linkedList.insert_before(3.5,4);
linkedList.insert_after(2.5,2);
linkedList.print();