오늘은 자료구조에 대해 포스팅 해보겠습니다 .
무수한 상황에서 데이터를 효율적으로 다룰 수 있는 방법을 모두 모아, 자료구조라는 이름을 붙였습니다. 우리는 이 많은 방법 중에서, 가장 많이 쓰이고 알고리즘 테스트(코딩 테스트)에 자주 등장하는 네 가지를 학습했습니다 .
Stack
그림을 예로 들어 설명하자면 Stack은 프링글스라고 할 수 있다.
위에 있는 감자칩을 먹어야, 그 아래 있는 감자칩을 먹을 수 있고,
감자칩을 통 속에 넣을 때는 중간에 끼워 넣을 수 없다.
그렇게 쌓아가는 게(stack) 스택이다.
스택에서 사용하는 용어
Stack의 수도코드
스택 생성{
비어있는 top;
비어있는 size;
}
스택.push(data){
data를 top에 입력;
top++;
}
스택.pop(){
top에 있는 데이터 return;
데이터 삭제 후;
top--;
}
Stack 코드의 응용
var Stack = function(){ // make Stack
this.top = null;
this.size = 0;
};
var Node = function(data){ // status of data now
this.data = data;
this.previous = null;
};
Stack.prototype.push = function(data) { // push for insert data
var node = new Node(data); // make new node(data)
node.previous = this.top;
this.top = node;
this.size += 1;
return this.top;
};
Stack.prototype.pop = function() { // pop for delete data
temp = this.top;
this.top = this.top.previous;
this.size -= 1;
return temp;
};
Queue
queue 는 줄 이라는 뜻입니다 줄을 세운다는 뜻으로 기본적으로 먼저 입력된것이 먼저 나가는 선입 선출의 방식으로 됩니다.
스택과 달리 큐는 입구와 출구가 구분되어 있기 때문에, 입구로 들어온 데이터는 반드시 반대쪽 출구로 나가야만 합니다.
속성
메소드 구현해보기
class Stack {
constructor() {
this.top = null;
}
makeNode(value) {
return {
value,
below: null,
};
}
push(...values) {
for (let value of values) {
const node = this.makeNode(value);
if (this.top === null) {
this.top = node;
} else {
node.below = this.top;
this.top = node;
}
}
}
pop() {
if (this.size() === 0) return;
let popped;
if (this.top && this.top.below) {
popped = this.top;
this.top = this.top.below;
} else {
popped = this.top;
this.top = null;
}
return popped.value;
}
contains(value) {
let clone = this.top;
while (clone !== null) {
if (clone.value === value) {
return true;
}
clone = clone.below;
}
return false;
}
size() {
let count = 0;
let clone = this.top;
while (clone !== null) {
count += 1;
clone = clone.below;
}
return count;
}
}
Stack 으로 Queue 구현하기
2개의 스택을 이용해 계량컵에 옮기듯 아이템들을 이동시켜 큐를 구현하는 방법이다. 이미 구현한 Stack을 통해 아이템을 추가(enqueue) 하기 위해 메인으로 사용할 스택(inbox)과 삭제(dequeue) 하기 위해 서브로 사용할 스택(outbox)을 만들어 사용한다.
class Queue {
constructor() {
this.inbox = new Stack();
this.outbox = new Stack();
}
enqueue(value) {
this.inbox.push(value);
}
dequeue() {
const size = this.inbox.size();
let temp_size = size;
while (temp_size > 0) {
this.outbox.push(this.inbox.pop());
temp_size -= 1;
}
const dequeued = this.outbox.pop();
temp_size = size - 1;
while (temp_size > 0) {
this.inbox.push(this.outbox.pop());
temp_size -= 1;
}
return dequeued;
}
contains(value) {
return this.inbox.contains(value);
}
size() {
return this.inbox.size();
}
}
Tree
일반적 트리구조
바이너리 트리 구조
Binary Search Tree의 규칙
현재 노드의 오른쪽에 있는 노드는 반드시 현재 노드보다 큰 값을 가지고 있다. 반대로 왼쪽에 있는 노드는 현재 노드보다 작은 값이다.
각 노드는 최대 2개의 노드만 가질 수 있다.(Binary)
insert와 delete의 경우, 마찬가지로 현재 노드보다 큰지 작은지를 기반으로 삭제/추가 해야 하는 값의 위치로 이동하게 된다. 그런데 만약 위 그림에서 105를 지우면, 이 자리를 대체할 값을 찾아야 하고 144가 105의 자리를 대체하게 된다. 만약 노드의 level이 아주 깊다고 할 경우에는 하단의 모든 level의 값을 하나씩 위로 올려야 하기 때문에 해쉬 테이블에서 값을 삭제할 때의 시간복잡도 O(1)보다 느릴 수 밖에 없다.
이진트리구조
이진 검색 트리는 위와 같이 생겼습니다. 잘 보시면 숫자가 정렬된 것을 알 수 있습니다. 가장 작은 숫자는 가장 왼쪽에, 가장 큰 숫자는 가장 오른쪽에 있습니다
완전 트리 구조
트리 구조 만들기
class CreatTree {
constructor() {
this.matrix = [];
}
addVertex() {
const currentLength = this.matrix.length;
for (let i = 0; i < currentLength; i++) {
this.matrix[i].push(0);
}
this.matrix.push(new Array(currentLength + 1).fill(0));
}
contains(vertex) {
return !!this.matrix[vertex]
}
addEdge(from, to) {
const currentLength = this.matrix.length - 1;
if (from === undefined || to === undefined) {
return;
}
/
if (
from > currentLength ||
to > currentLength ||
from < 0 ||
to < 0
) {
return;
}
this.matrix[from][to] = 1;
}
hasEdge(from, to) {
return !!this.matrix[from][to]
}
removeEdge(from, to) {
const currentLength = this.matrix.length -1;
if (from === undefined || to === undefined) {
return;
}
if (
from > currentLength ||
to > currentLength ||
from < 0 ||
to < 0
) {
return;
}
//TODO: 간선을 지워야 합니다.
this.matrix[from][to] = 0
}
}
Graph
그래프 란?
그래프는 상하위의 개념이 없이 각각의 node와 그 node들 간의 간선(edge)을 하나로 모아 놓은 자료구조이다.
그래프의 특징
그래프는 꼭 모든 node들이 서로 관계를 갖고 있어야만 하지 않다. 따라서 그래프는 node간 연결이 없는 고립된 부분이 있을 수도 있고, 순환할 수도 있고, 안할 수도 있기 때문에 가장 형식에 얽매이지 않은 자료구조라고 볼 수 있다.
그래프 자료구조에서 사용하는 용어
그래프 구조의 수도 코드
새로운 Graph {
그래프 생성자{ 비어있는 노드 리스트 }
노드 생성자 {
노드 이름;
노드와 연결된 노드 리스트[]; //edge
}
노드 입력 {
data = new 노드;
while(edge수){
연결되는 노드에도 edge 추가
}
return graph;
}
}