Read Chapter 8.
1. Prove that the smallest height for any tree on n nodes is Ω(lg n) = - 1 + lg(n+1).
2. When you shrink the space of direct access arrays, you might want to use a linked list data structure. What would be the problem if you use the linked list? Show your answer with explaining the time complexity.
3. In the hash family function, a should not equal to 0. Why? Please give me a simple answer (one sentence).
4. Use the birthday dataset, Do the followings:
4.1. Put them into your unordered array using set.
4.2. Put them into the sorted array set.
4.3. Put them into the direct access array set
4.4. Put them into the hash table set.
4.5. Compare their size.
4.6. Compare their interfaces: build, find, insert, delete, find_min, find_max, find_next, find_prev.
트리에서 높이란, 루트에서 해당 노드에 이르는 경로에 있는 간선의 수를 의미한다.
즉, 해당 노드의 레벨에서 루트 노드의 레벨(0)을 빼준 값이다.
완전 이진트리에서, n을 노드의 개수라고 했을 때
n = 1 : 높이 0 (루트 노드 그 자체)
n = 2 ~ 3 : 높이 1
n = 4 ~ 7 : 높이 2
n = 8 ~ 15 : 높이 3
이런 식으로 진행된다.
높이가 h인 이진트리가 가질 수 있는 노드의
최소 개수는 (h+1)개이다.

한 레벨에 최소한 한 개의 노드가 있어야 하므로 높이가 h인 이진트리의 최소 노드의 개수는 (h+1)개가 된다.
최대 개수는 2^(h+1)-1 개이다.
2^i 이다.레벨 0에서의 노드의 최대 개수 : 1
레벨 1에서의 노드의 최대 개수 : 2^1 = 2
레벨 2에서의 노드의 최대 개수 : 2^2 = 4
레벨 3에서의 노드의 최대 개수 : 2^3 = 8
...
높이가 3인 이진 트리에서 최대 노드의 개수
= 레벨 0에서의 노드의 최대 개수
+ 레벨 1에서의 노드의 최대 개수
+ 레벨 2에서의 노드의 최대 개수
+ 레벨 3에서의 노드의 최대 개수
= 1 + 2 + 4 + 8
= 2^(3+1) - 1
= 15
...
이를 일반화하면
따라서 높이가 h인 이진 트리에서 최대 노드의 개수 : 2^(h + 1) - 1위와 같은 과정을 통해 최대 개수는 2^(h+1)-1 개인 것을 알 수 있다.
따라서 이 식에서 출발하면
2^(h + 1) - 1 = n
2^(h + 1) = n + 1
양변에 로그를 취하면
h + 1 = log(n + 1)
따라서 h = log(n + 1) - 1
으로 증명할 수 있다.
출처 : https://leejinseop.tistory.com/40, https://kuminkyu93.tistory.com/69
Direct access arrays는 일반 Array 배열이나 자바에서의 ArrayList를 생각해 볼 수 있겠고,
Linked list는 포인터를 이용해 다음 노드를 가리키는 LinkedList를 생각해 볼 수 있다.
대표적으로 자바의 ArrayList와 LinkedList를 예로 들어서 생각해보겠다.

ArrayList는 데이터들이 순서대로 쭉 늘어선 배열의 형식을 취하고 있고, 인덱스로 접근한다.
LinkedList는 자료의 주소 값으로 서로 연결되어 있는 구조이고, 다음 노드를 가리키는 포인터를 통해 접근한다.
LinkedList로 바꾸면 조회 시 시간 복잡도가 O(N)으로 증가한다는 단점이 있다.
출처 : https://www.nextree.co.kr/p6506/
package week3;
import java.util.*;
public class homework3_compare {
public static void main(String[] args) {
CSVReader csvReader = new CSVReader();
List<List<String>> list = csvReader.readCSV();
// 4.1. set을 이용해 정렬되지 않은 배열에 넣기
HashSet<List<String>> set = new HashSet<>();
for (List<String> node : list) {
set.add(node);
}
// 4.2. 정렬된 배열 집합에 넣기
// 정렬된 배열 집합 자동으로 정렬해주는 우선순위 큐에 저장했습니다.
// 틀릴 수도 있지만 자동으로 정렬해준다는 점에서 이용해 보았습니다.
PriorityQueue<List<String>> pq = new PriorityQueue<>(new Comparator<List<String>>() {
@Override
public int compare(List<String> o1, List<String> o2) {
return (int) (Double.parseDouble(o1.get(2)) - Double.parseDouble(o2.get(2)));
}
});
for (List<String> node : list) {
pq.add(node);
}
// 4.3. Direct Access Array set에 넣기
// 직접 접근할 수 있는 것은 ArrayList라고 판단해 ArrayList를 이용해 보았습니다.
ArrayList<List<String>> al = new ArrayList();
for (List<String> node : list) {
al.add(node);
}
// 4.5. 크기 비교
System.out.println("1) set : " + set.size());
System.out.println("2) PriorityQueue : " + pq.size());
System.out.println("3) ArrayList : " + al.size());
}
}
크기 비교 결과 사진 :


위의 표를 통해 비교해볼 수 있다.
정렬되지 않은 일반 Array의 경우
정렬된 Array의 경우
Direct Access Array set의 경우