참고 1. Tree, Queue, Stack


Sanjoy Dasgupta가 저술한 책인 Algorithms과 이기창님의 블로그, Heee님의 블로그를 참고하였다.


1-1. Tree(트리)

트리를 재귀적 형태로 정의하면 다음과 같다

재귀적 형태(Recurrence Relation) : 수열의 항 사이에서 성립하는 관계식. 즉, 자기 자신을 호출하는 점화식(ex. 피보나치 수열, 퀵소트

Tree(트리) : 루트노드가 0개 이상의 자식 노드를 갖고, 그 자식 노드가 또 0개 이상의 자식 노드를 갖는 형태의 자료구조


1-2. Tree(트리)의 특징


1-3. Tree(트리)의 종류

이진 트리(Binary Tree) : 각 노드가 최대 두 개의 자식을 갖는 트리

cf) K-ary Tree : 각 노드가 최대 $k$ 개의 자식을 갖는 트리

이진트리를 기준으로 종류를 나누면 다음과 같다.

앞서 공부한 힙 정렬에 사용되는 max heap과 min heap은 모두 이진트리를 기반으로 만들어진 것이며, 앞으로 공부할 이진탐색트리(BST. Binary Search Tree)도 이진트리를 기반으로 만들어진 기법이다.

 이진탐색트리 : 왼쪽 서브트리 $\leq$ 노드 $\leq$ 오른쪽 서브트리의 성질을 만족하는 이진트리


1-4. Tree Traversal(트리 순회)

트리순회 : 트리의 각 노드를 체계적인 방법으로 방문하는 과정

따라서, 다음 트리를 트리순회 방식대로 방문하면 다음과 같다.

Preorder : 1, 2, 4, 5, 3

Inorder : 4, 2, 5, 1, 3

Postorder : 4, 5, 2, 3, 1

만약 Binary Tree를 K-ary Tree로, 혹은 K-ary Tree를 Binary Tree로 바꾸고 싶다면 기존 Tree의 Tree Traversal 방식을 고려하여 바꿔주어야 한다.


1-5. Tree(트리) 관련 알고리즘


2-1. Queue

한쪽 끝으로 자료를 넣고, 반대쪽에서는 자료를 뺄 수 있는 자료구조

먼저 넣은 데이터가 먼저 나오는 FIFO(First In, First Out) 구조로 저장한다.(그림출처)

위 그림에서는 Front, Rear이지만 Head, Tail로 바꿔 읽어주자.

Enqueue : 데이터 삽입. 큐에 새로운 데이터가 들어오면 큐의 끝 위치(Tail)에 저장됨

Dequeue : 데이터 삭제. 삭제할 때는 첫번째 위치(Head)의 요소가 삭제됨


2-2. Queue(큐)의 구현

Enqueue와 Dequeue를 이용해 Queue를 구현한다. 구현 방식으로는 연결리스트를 이용하는 것과 배열을 이용하는 것이 있다.

다음의 enqueue와 dequeue의 예시로 Queue를 구현해보자.

enqueue 5, enqueue 3, enqueue 1, dequeue, dequeue, enqueue 7


그렇다면 배열로 큐를 구현할 때, dequeue의 시간복잡도를 $O(1)$로 줄이려면 어떻게 해야할까?

Circular Array로 Queue를 구현하면 이를 해결할 수 있다. 즉, 위처럼 일련의 딱딱한 배열이 아니라, 원으로 Head와 Tail이 이어진 Circular Array를 이용하면 되는 것이다.

나중에 공부하겠지만 큐를 이용해서 “우선순위 큐”라는 것을 만들 수 있는데, 이는 우선순위를 가진 데이터를 저장하는 큐를 말한다. 즉, 일반적인 큐는 FIFO 방식대로 먼저 들어갔으면 먼저 나오게 되는데, 우선순위 큐는 들어간 순서에 상관없이 우선순위가 높은 데이터가 먼저 나오는 것이다.


3-1. Stack(스택)

한쪽 끝에서만 자료를 넣고 뺄 수 있는 LIFO(Last In, First Out) 형식의 자료구조

책이 쌓여있는 것을 생각하면 쉽다. 쌓여있는 책 중 가장 최근에 놓은 책(가장 위에 있는 책)을 먼저 꺼낼 수 있는 것처럼 Stack도 가장 마지막에 넣은 데이터를 먼저 꺼낼 수 있는 것이다.

Push : 자료를 넣음

Pop : 자료를 꺼냄

만약 6, 4, 2를 차례대로 Push하고, 두 번 Pop한 다음, 7을 Push한다면 그 과정은 다음과 같다.

6  … 6, 4 … 6, 4, 2 … 6, 4 … 6 … 6, 7


3-2. Stack(스택)의 구현

Push와 Pop을 이용해 Stack을 구현한다. 구현 방식으로는 리스트, 연결리스트 등 다양한 자료구조로 가능하다.

리스트의 경우 파이썬 문법처럼 Append로 새 자료를 넣고, 제거할 때는 Pop하면 된다. 어떤 자료구조를 사용하던 각 행위의 시간복잡도는 모두 $O(1)$이다.


3-3. Stack(스택)의 활용

Stack이 활용되는 대표적인 사례는 재귀함수이다.

이밖에도 웹 브라우저의 방문기록(뒤로가기), 실행 취소(undo) 등에도 Stack이 활용된다.


지금까지 자료구조로 Tree와 Queue, Stack에 대해 알아보았다.

이 밖에도 대표적인 자료구조로 Heap과 Graph가 있는데, Heap은 이미 공부했고 Graph는 앞으로 자세히 공부할 예정이라 이 포스팅에는 적지 않았다.