추상 자료 구조의 기본적인 구조!
후입선출의 Stack
, 선입선출의 Queue
에 대해 알아보겠다.
Stack
데이터가 들어가는 선형 자료형(linear)이다. 무슨말일까.. 하고 찾아보니 직선적인 구조라고 한다. 후입선출의 구조로, 프링글스 통을 생각해보면 좋을 것 같다.
내가 좋아하는 프링글스 갈릑맛은 녹색 원통에 과자가 겹겹이 쌓여 있다.
갈릭이 아니라 사워크림&어니언이었다. 아무튼,,
만약 공장이 아니라 사람이 프링글스를 하나하나 만든다고 생각한다면,
정성스레 만든 과자 한겹 한겹을 아래부터 쭉쭉 채울 것이다.
..아마 공장에서도 아래부터 한겹 한겹 채울 것이다.
let 프링글스통 = [];
let 과자1 = '감자와 소금과 갖가지 조미료가 짜게 어우러진 감자칩';
let 과자2 = '감자와 소금과 갖가지 조미료가 짜게 어우러진 감자칩';
let 과자3 = '감자와 소금과 갖가지 조미료가 짜게 어우러진 감자칩';
let 과자4 = '감자와 소금과 갖가지 조미료가 짜게 어우러진 감자칩';
.
.
.
프링글스통.push(과자1);//push메서드는 배열의 맨 뒤에 요소를 추가하고, 선언된 변수가 있다면 그에 추가한 후 배열의 길이를 할당한다.
프링글스통.push(과자2);
프링글스통.push(과자3);
프링글스통.push(과자4);
프링글스통.push(과자5);
프링글스통.push(과자6);
.
.
.
프링글스통.push(과자50);
console.log(프링글스통);//[과자1,과자2,과자3,...,과자50]
이런식으로 말이다. 그렇다면 우리가 먹을땐 어떨까..?
물론 뚜껑에 뭉텅이를 꺼내 먹는 방법도 있지만, 우리는 교양인이다.
고급지게 하나씩 꺼내 먹는다고 생각했을 때, 맨 위의 과자부터 먹는다.
프링글스통.pop();//과자50 //pop메서드는 배열 맨 뒤의 요소를 제거하고, 선언된 변수가 있다면 그에 할당한다.
프링글스통.pop();//과자49
프링글스통.pop();//과자48
.
.
.
이렇게 먹을 것이다. 이 것이 Stack
의 구조를 구체화 한 것으로 볼 수 있다.
Stack
은 서로 연관 관계가 있는 작업들을 저장하는 데에 주로 쓰인다. 브라우저의 뒤로가기, 앞으로 가기 버튼도 Stack
구조형을 썼다고 볼 수 있다.
Queue
Queue
도 선형 자료형으로, 선입 선출의 구조다.
먼저 들어온 것이 먼저 나간다는,, 자료 구조다.
아무튼 이것도 쉽게 설명하자면,,
우리는 하루에 세끼를 먹는다.
그리고,,, 차례로 배출한다.
이를 코드로 구현해보자.
class 몸(){
constructor(){
this.arr = [];
}
enqueue(meal){
this.arr.push(meal);
}
dequeue(){
return this.arr.shift()
}
}
let 몸뚱아리 = new 몸();
몸뚱아리.enqueue('아침밥');
몸뚱아리.enqueue('점심밥');
몸뚱아리.enqueue('저녁밥');
몸뚱아리.dequeue();//'아침밥'
이런 느낌으로 구현이 된다. 먼저 들어간 것이 먼저 나오는 자료 구조형으로, 주로 쓰이는 방법은 Queue
(몸뚱아리)안에 순서대로 처리할 작업(배출)을 임시로 저장해 두는 버퍼('buffer', 소화중,,)로 사용된다.
Stack
,Queue
는 데이터의 추상적 형태와 그 데이터를 다루는 방법을 정해둔 것이다. 이와 같은 자료형을 추상자료형(ADT, Abstract Data Type)이라고 한다.
이와 같은 추상자료형은 데이터를 다루는 데 있어 구현자와 사용자를 구분해주는데, 중요한 로직을 은닉할 수도 있고, 사용자로 하여 내부 구현을 알지 않아도 데이터를 다룰 수 있게 한다는 장점이 있다.