-
자료구조 1학교 수업/자료구조 2020. 5. 15. 11:45
자료구조에서 배웠던, 여러 자료들에 대해서 간략히 설명하겠다.
ADT(Abstract Data Type): 컴퓨터 과학에서 자료들과 자료들에 대한 연산들을 명기한 것.
자료구조의 추상화
1. Array
- 장점: 배열에서 특정 위치의 값을 찾기에 편리하다.
- 단점: 배열의 크기를 넘는 값을 삽입할 경우 문제 / 배열의 중간에 삽입 or 삭제 연산 시 번거로움 발생
2. Linked List
- 선형으로 연결된 노드들을 가지는 자료구조
- 노드간 pointer를 이용해 list를 구현하므로 메모리에 연속적으로 값을 저장할 필요 없다.
- Array list와 달리, 추가 및 삭제가 쉽지만 데이터 접근 시 최악의 경우 O(n) time 소요
- 3가지로 나뉨
1) Single Linked list
- 한방향으로 연결된 리스트로, 각 node는 element와 다음 node의 pointer로 구성
(노드 사이의 간선이 단방향으로 하나씩만 존재)
- ADT method: empty(), front(), addFront(), removeFront()
2) Double Linked list
- 양방향으로 연결된 리스트로, 각 node는 element, next pointer, prev pointer로 구성
(노드 사이의 간선이 양방향으로 2개씩 존재)
- 노드의 탐색이 양방향으로 가능하므로 탐색 양이 single에 비해 절반 감소한다.
- ADT method: empty(), front(), back(), addFront(), removeFront(), addBack(), removeBack()
3) Circular Linked list
- Single linked list의 구조를 원형으로 만든 자료구조
(첫번째 노드와 마지막 노드가 연결)
- 마지막 노드를 참조하는 cursor가 single에서의 head역할을 한다.
3. stack
- LIFO원칙에 따라 자료를 삽입 또는 삭제하는 자료구조
- ADT method: push(object), pop(), top(), size(), empty()
- Exceptions: stack이 빈 상태일 때, pop(), top()연산 수행 시 StackEmpty exception 발생
- C++ Run-Time Stack: c++ run-time system은 stack을 이용하여 active function들의 chin track을 유지한다. 함수 호출 시 시스템은 호출된 함수에 관한 정보(지역변수, 반환 값, pc, 현 실행지점)를 포함하는 하나의 frame을 stack에 push한다. 함수 종료 시 해당 frame이 pop되고 stack의 top함수가 수행됨
- 구현 방법
1) Array-based Stack
- 공간 복잡도: O(n)
- 시간 복잡도: push(object), pop(), top(), size(), empty() 모두 O(1)
- 한계: 배열을 사용하기 때문에 stack크기 조정 불가능하다.
따라서 full stack에 대해 push()연산 수행 시 StackFull exception발생 ç implementation-specific exception
2) Linked list-based Stack
- Single linked list로 구현
- 배열과 달리 full stack문제가 발생하지 않는다. 크기 제한이 없어서.
- 공간 복잡도: O(n)
- 시간 복잡도: 모든 연산에 대해 O(1)
4. queue
- FIFO원칙에 따라 자료를 삽입 또는 삭제하는 자료구조
- ADT method: size(), empty(), enqueue(object), dequeue(), front()
- Exceptions: 빈 큐에 대해 dequeue()와 front()연산 수행 시 QueueEmpty exception 발생
- 구현 방법
1) Array-based Queue
- 크기가 N인 circular array를 사용한다. (현재 front의 인덱스, 원소의 크기, 배열의 크기를 따로 지정한 변수에 저장)
- Full queue에 대해 enqueue(e)연산 수행 시 QueueFull exception발생 ç implementation-specific exception
- 공간 복잡도: O(n)
- 시간 복잡도: 모든 연산에 대해 O(1)
2) Linked list-based Queue
- Circular linked list이용하여 구현
- 공간 복잡도: O(n) (n: queue에 저장된 요소의 개수)
- 시간 복잡도: O(1)
5. vector
- Linked list의 장점을 뽑아온 자료구조
- Index를 이용하여 element에 대한 접근, 삽입 그리고 삭제를 지원하는 자료구조
- ADT method: at(i), set(i, object), insert(i, object), erase(i), size(), empty()
- Exceptions: 부정확한 index가 주어질 경우 예외처리
- 구현 방법
1) Array-based 구현
- 크기가 N인 배열 사용하며 저장된 요소의 개수를 변수 n에 저장
- 공간 복잡도: O(N)
- 시간 복잡도
Size()
Empty()
At(i)
Set(i, e)
Insert(i, e)
Erase(i)
O(1)
O(1)
O(1)
O(1)
O(n)
O(n)
- 배열이 full일 때 insert()연산을 수행할 경우: 예외처리를 하는 대신 더 큰 배열로 배열을 교체한다.
배열 크기 확장 ç 값을 옮기면서 O(n)의 시간이 필요함.
① Incremental strategy : 상수만큼 더 큰 배열
② Doubling strategy : 기존배열의 두배
6. Tree
- List와 vector가 선형구조인 반면, tree는 계층적 구조를 가진다.
- 노드간 부모-자식 관계가 존재
- 용어
① Root: tree에서 부모가 없는 최상위 노드
② Internal node: 1개 이상의 자식 node가 존재하는 node
③ External node: 자식이 존재하지 않는 node로 leaf를 뜻한다.
④ Ancestors of a node: 한 노드의 부모를 포함한 조상 노드들
⑤ Descendant of a node: 한 노드의 바로 연결된 자식과 그 밑 자식들
⑥ Depth: 한 노드의 조상의 수
⑦ Height: 노드들의 depth중 가장 큰 depth로, tree의 높이다.
⑧ Subtree: tree의 한 노드와 그 후손들로 구성된 하나의 트리 (트리안에 트리)
⑨ Sibling: 같은 부모 노드를 가진 자식 노드들의 관계
- ADT method: size(), empty(), root(), positions() (모든 노드들의 위치 list), parent(), children(), isRoot(), isExternal()
- 트리의 순회(Traversal) 방법
① Preorder Traversal: 부모 à 자식(왼->오)순으로 방문한다. 주로 책의 목차를 print할 때 사용
② Postorder Traversal: 자식 à 부모순으로 방문한다. 주로 하위 디렉토리들이 차지하는 공간의 용량을 계산할 때 사용
- Binary tree
- 트리중 모든 노드가 최대 두개의 자식 노드를 가진 트리
- 종류
① Proper(=full=plane) binary tree: 모든 노드가 0 or 2개의 자식을 가진 tree
② Complete(=perfect) binary tree: 모든 internal 노드가 2개의 자식을 가지며 leaf 노드들의 깊이가 모두 같은 tree)
③ Almost complete(=complete) binary tree: complete tree에서 모든 leaf노드들이 왼쪽부터 오른쪽 방향으로 채워진 tree
Complete binary tree를 perfect binary tree라 지칭할 경우 almost complete를 complete라고도 부름
- 응용: 수식표현, decision tree, searching(binary search tree)
- ADT method: Tree ADT의 함수들 + left(), right()
- Binary Tree의 Traversal : Tree 순회방법에서 하나 더 추가됨
① Preorder: 부모à왼쪽 자식à오른쪽 자식 순서로 순회
② Postorder: 왼쪽 자식 à 오른쪽 자식 à 부모 순서로 순회
③ Inorder: 왼쪽 자식 à 부모 à 오른쪽 자식 순서로 순회
④ Euler Tour Traversal
Ø preorder, inorder, postorder traversal을 모두 실행한다.
Ø Tree 주위를 순회하며 각 node를 3번 방문(왼쪽 자식 방문 전, 왼쪽 자식 방문 후 오른쪽 자식 방문 전, 오른쪽 자식 방문 후)한다.
Ø 한 노드당 하는 일의 수가 모두 3개로 일정하여 이 순회의 시간 복잡도는 O(n)
- 구현 방법
1) Linked list-based: 각 노드는 element, parent node, left child, right child로 구성
2) Array-base: 노드가 깊이 순서로 배열에 저장. Root=1, 왼쪽 자식=2*i, 오른쪽 자식=2*i+1
7. priority queue
- 우선순위에 의해 데이터가 정렬되기 때문에 queue에 삽입되는 요소의 순서가 중요하지 않으며 데이터 속성에 따라 제거가 가능하다.
- ADT에서 Entry는 (key, value) 쌍으로 구성되며 key는 우선순위를 가리킴
- ADT method: insert(e), removeMin(), min(), size(), empty()
- 구현 방식
List-based Priority queue
List를 정렬된 상태로 저장 vs 정렬되지 않은 상태로 저장 수행 시간 비교
(sorted list) (unsorted list)
Operation
Unsorted List
Sorted List
Size, empty
O(1)
O(1)
Insert
O(1)
O(n)
Min, removeMin
O(n)
O(1)
- PQ를 이용한 sort 방법들 -> 정렬을 위해 insert, removeMin연산을 이용
Priority queue에 n개의 원소를 삽입(insertion)하는 시간 = 1*n
Priority queue에서 원소 하나씩 꺼내어 기존 배열에 옮기는 작업(removeMin) 시간 = 1+2+…+n
=> n+1+2+3+…+n = O(n^2)
1) selection-sort : unsorted list를 사용하여 O(n^2)에 동작가능.
- 실제 selection sort는 주어진 배열에서 0부터 n-1까지의 i에 대하여 [i, n]구간에 대하여 가장 최솟값을 맨 앞에 세우는 과정을 반복.
2) insertion-sort : sorted list를 사용하여 O(n^2)에 동작가능.
구현
시간 복잡도
Selection-Sort
Unsorted List를 이용한 PQ
O(n^2)
Insertion-Sort
Sorted List를 이용한 PQ
O(n^2)