Posts 데이터 자료구조. Stack / Queue
데이터 자료구조. Stack / Queue
Cancel

데이터 자료구조. Stack / Queue

1. 자료 구조 (Data Structure)

  • 데이터 타입 : 하나의 데이터를 어떻게 해석할지 정의한 것.
  • 자료 구조 : 여러 데이터들의 묶음을 어떻게 저장하고 사용할지 정의한 것

2. Stack

image

먼저, 스택은 한 쪽 끝에서만 자료를 넣거나 뺄 수 있따. 위 사진 처럼.
이런 구조를 LIFO: last in, first out 라고 한다.
가장 최근에 넣은 자료부터 추출할 수 있다는 것.
** 1,2,3,4,5 를 순서대로 넣으면 꺼낼 때는 5,4,3,2,1 로 꺼내야 한다.**

image 요 그림이나, 프링글스를 생각하면 쉽다.
넣은 순서대로 꺼낼 수 있는 것이 아니라, 가장 마지막에 넣은 것부터 꺼낼 수 있는 구조. 오키?

Stack에는 기본 내장 메소드가 6개가 있다.

  • push(): 값을 추가
  • pop(): 값을 제거
  • peek(): 제일 위에 있는 값을 추출
  • isEmpty(): 스택이 비어 있으면 true, 아니면 false
  • clear(): 스택의 모든 내용을 제거.
  • size(): 스택의 길이.

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
class Stack {
	constructor() {
		this.storage = {}; // 내가 저장할 빈 객체. 혹은 빈 배열도 가능 // this.storage ={} 말고 storage = {} 해도 괜찮음.
		this.top = -1; // -1이면 객체의 시작을 0으로 한다는 것. 0이면 1로 시작.
	}
	size() {
		return this.top + 1; // 객체에 길이. 값을 몇 번이나 추가 했는지 알려주는 것.
	}

	push(element) {
		this.top++; // 값을 넣기 전에 우선 top의 값을 올려준다.
		this.storage[this.top] = element; // 그리고 그 객체에 키를 this.top으로 주고, 값을 element.
	}

	pop() {
		if (this.top < 0) {
			// 빈 객체여도 pop의 명령어가 오류를 뱉지 않도록 만들어주는 조건문.
			return;
		}
		let pop = this.storage[this.top]; // 우선 추출할 값을 할당을 해줘야 한다.
		delete this.storage[this.top]; // 값을 할당 후 추출할 값을 객체에서 삭제.
		this.top--; // 그리고 나서 키 값을 1개를 줄여줘서 이후 push를 할 때 this.top의 값이 정상적으로 나오기 위함.
		return pop; // 그리고 나서 할당해 줬던 값을 추출.
	}
}

코드이다.
this 때문에 보기가 불편하지만 어쩔 수 없다. 나만 불편해?

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
push 부분 자세히 보기
stack.push('a')  // this.storage = {0: 'a'}
stack.push('b') // this.storage = {0: 'a', 1: 'b'}
stack.push('c') // this.storage = {0: 'a', 1: 'b', 2: 'c'}
이렇게 나온다. this.top이 this.storage의 키가 되고,
element는 this.storage[this.top] value가 된다.

this.top의  값이 -1이고 이후 pop할 때마다 ++ 되기 때문에 객체 시작은 0.

pop 부분 자세히 보기
stack.pop() // this.storage = {0: 'a', 1: 'b'}
return = 'c'
stack.pop() // this.storage = {0: 'a'}
return = 'b'
이렇게 나온다.

1. let pop = this.storage[this.top] 통해
let pop = 'c' 되게 만들어 준다. this.storage[this.top] value를 우선 담아주자.

2. delete this.storage[this.top] 통해
{0: 'a', 1: 'b', 2: 'c'} --> {0: 'a', 1: 'b'}

3. This.top -- ==> 3에서 2 값을 낮춤. 그래야지 push를   다시 3으로 .
(만약 하지 않는다면 다음 push를   {0: 'a', 1: 'b' 3: 'c'} 형태가 된다.

4. Return pop => 'c'
 순서를 지켜야 추출과 동시에 객체에서 삭제할  있다.

3. Queue

큐는 스택과 조금 다르다.
먼저 집어 넣은 데이터가 먼저 나오는 FIFO (First In First Out)구조.
가장 먼저 넣은 애가 값으로 나온 다는 것.
1,2,3,4,5 로 넣었으면 나올 때도 1,2,3,4,5가 된다.

놀이동산 줄 기다리는 거, 게임 큐 잡힌다고 하는 것 등 예시가 많다.

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
class Queue {
	constructor() {
		this.storage = {}; // 빈 객체를 지정. 여기다가 데이터를 넣을 것이다.
		this.front = 0; // 객체의 시작 부분 // 우리가 추출할 부분
		this.rear = 0; // 객체의 끝 부분 // 데이터가 들어가는 곳.
		// 스택은 출입구가 똑같아 1개지만 큐는 입구와 출구가 달라 front/rear로 나뉘는 것.
	}

	size() {
		return this.rear - this.front; // 객체의 전체 길이
	}
	enqueue(element) {
		this.storage[this.rear] = element; // 이번에는 초기 값이 0이니 먼저 데이터를 넣고 그 이후에 ++
		this.rear++;
	}
	dequeue() {
		if (this.rear - this.front < 1) {
			return; // 객체가 비어도 계속 사용할 수 있게.
		}
		let removed = this.storage[this.front]; // 추출할 값을 먼저 할당
		delete this.storage[this.front]; // 그리고 추출할 값을 객체에서 삭제
		this.front++; // 삭제하고 나서 ++를 해줘야지 그 다음 객체를 삭제할 수 있다.
		return removed; // 삭제한 값 추출
	}
}
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
enqueue('a') // this.storage === {0: 'a'}
enqueue('b') // this.storage === {0: 'a', 1: 'b'}
enqueue('c') // this.storage === {0: 'a', 1: 'b', 2: 'c'}
데이터가 이렇게 들어간다.
스택과는 달리 ++ 뒤에 넣은 점은, 시작이 0이기 때문에.

dequeue로 자료 빼기.
this.storage === {0: 'a', 1: 'b', 2: 'c'}
dequeue() // this.storage === {1: 'b', 2: 'c'}
return 'a'
dequeue() // this.storage === {2: 'c'}
return 'b'

1. let removed === this.storage[this.front]  담자.
그러면 let removed === 'a' 된다. 추출할 값을 먼저 담아야 .
(위의 스택과 같다)

2. delete this.storage[this.front] ==
여기서 현재 this.top의 값은  위에 0으로 설정되어 있기에 객체에서 0 부분,
 가장 먼저 enqueue로 넣은  삭제하는 .

3.  이후 this.front의 값을 ++ 해준다. 그래야지 dequeue를    썼을 
this.storage[this.front] === this.storage[1]이라서 다음 값을 추출할  있다.
(처음에는 front가 0이라서 this.storage[this.front] === this.storage[0]
dequeue를 하고 나면 남은 객체는 {1: 'b', 2: 'c'}이다. ++ 통해
this.storage[this.front] === this.storage[1] 만들어 주자.)

4. 1번에서 담아준 'a' 리턴.

This post is licensed under CC BY 4.0 by the author.

TIL 38일차

원사자료 vs 참조자료

Comments powered by Disqus.