์๋ฃ๊ตฌ์กฐ
1. Array, Vector, Linked list
โ Array, Vector: ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ๊ธฐ๋ฐ์ ์ฐ์ ๋ฐฉ์
โ Linked List: ํฌ์ธํฐ ๊ธฐ๋ฐ์ ์ฐ๊ฒฐ ๋ฐฉ์
Array(์ ์ ๋ฐฐ์ด)
โ ์ ์ ๋ฐฐ์ด
โ ํฌ๊ธฐ๋ฅผ ์ง์ ํ๊ณ ํด๋น ํฌ๊ธฐ๋งํผ์ ์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋น๋ฐ๋ ์๋ฃํ
โ ํ๋ฒ ์์ฑํ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ ๊ณ ์ ๋๋ค
โ ์กฐํ: O(1) / ํ์: O(N)
โ ์ญ์ / ์ฝ์ : O(N)
- ๊ธฐ์กด ์์๋ค์ ์ด๋ ์์ผ์ค์ผ๋๋ค.
int[] numbers = new int[5];
numbers[0] = 10;
numbers[1] = 15;
numbers[2] = 20;
numbers[3] = 30;
numbers[4] = 40;
Vector(๋์ ๋ฐฐ์ด)
โ ๋์ ๋ฐฐ์ด
โ ์ ์ฒด ํฌ๊ธฐ๋ฅผ ๊ฐ๋ ํ๊ธฐ ํ๋ ๋ฐ์ดํฐ๋ ๋ง๋ค! -> ์๋์ผ๋ก ํฌ๊ธฐ ์กฐ์
- ์ด๊ธฐ ๊ฐ์ ์๊ฒ ์ก์ ๋ฐฐ์ด ์์ฑ
- ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ ๋ผ์ ๊ฝ ์ฑ์์ง ๋๋ง๋ค ๋๋ ค์ค๋ค (Doubling)
- Python(CPython) ๊ฐ์ ๊ฒฝ์ฐ ์ด๊ธฐ์๋ 2๋ฐฐ, ์ ์ฒด์ ์ผ๋ก๋ 1.125๋ฐฐ
- Java์ ArrayList ๊ฐ์ ๊ฒฝ์ฐ๋ 1.5๋ฐฐ
โ ์กฐํ: O(1) / ํ์: O(N)
โ ์ญ์ / ์ฝ์ : O(N)
- ๊ธฐ์กด ์์๋ค์ ์ด๋ ์์ผ์ค์ผ๋๋ค.
ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Linked List (์ฐ๊ฒฐ ๋ฆฌ์คํธ)
โ ํฌ์ธํฐ๋ฅผ ํ์ฉํด ์ฐ๊ฒฐ
- ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐ์์ ์ผ๋ก ์ฌ์ฉํ์ง ์์ ๊ด๋ฆฌ ์ฉ์ด
โ ๋์ ์ผ๋ก ์๋ก์ด ๋ ธ๋ ์ฝ์ /์ญ์ ์ฉ์ด
- ๊ธฐ์กด ์ฐ๊ฒฐ์ ๋๊ณ ํฌ์ธํฐ๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค
โ ์ฝ์ /์ญ์ : O(1) / ์กฐํ: O(N)
class Node {
int value;
Node next;
Node(int value, Node next) {
this.value = value;
this.next = next;
}
}
Node head = new Node(1, new Node(2, new Node(3)));
2. Stack, Queue
Stack
โ LIFO (Last In First Out): ํ์ ์ ์ถ
โ ์ฌ๊ท, ๋ฉ๋ชจ๋ฆฌ(์คํ ์์ญ)์์ ์ฌ์ฉ
import java.util.Stack;
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack); // Output: [3, 2, 1]
System.out.println(stack.peek()); // Output: 3
System.out.println(stack); // Output: [3, 2, 1]
System.out.println(stack.pop()); // Output: 3
System.out.println(stack); // Output: [2, 1]
Queue
โ FIFO (First In First Out): ์ ์ ์ ์ถ
โ BFS, ์ค์ผ์ค๋ง์ ์ฌ์ฉ
import java.util.LinkedList;
LinkedList<Integer> queue = new LinkedList<>();
queue.add(1);
queue.add(2);
queue.add(3);
System.out.println(queue); // Output: [1, 2, 3]
queue.add(4);
System.out.println(queue); // Output: [1, 2, 3, 4]
System.out.println(queue.remove()); // Output: 1
System.out.println(queue); // Output: [2, 3, 4]
3. Deque
โ Double Ended Queue
โ ์์ชฝ ๋์์ ์์์ ์ฝ์ ๊ณผ ์ญ์ ๊ฐ ๊ฐ๋ฅํ ์๋ฃํ (ํ + ์คํ)
import java.util.Deque;
import java.util.ArrayDeque;
Deque<Integer> deque = new ArrayDeque<>();
deque.addFirst(1);
deque.addFirst(2);
deque.addLast(3);
deque.addLast(4);
System.out.println(deque); // Output: [2, 1, 3, 4]
System.out.println(deque.removeFirst()); // Output: 2
System.out.println(deque.removeLast()); // Output: 4
System.out.println(deque); // Output: [1, 3]
System.out.println(deque.peekFirst()); // Output: 1
System.out.println(deque.peekLast()); // Output: 3
4. Priority Queue, Heap
Priority Queue(์ฐ์ ์์ ํ)
โ ํน์ ์กฐ๊ฑด(์ต์, ์ต๋ ๋ฑ)์ ๋ฐ๋ผ ์ฐ์ ์์๊ฐ ๋์ ์์๊ฐ ์ถ์ถ๋๋ ์๋ฃํ
โ ์ผ๋ฐ์ ์ผ๋ก ํ(Heap)์ ์ด์ฉํด ๊ตฌํ
โ ์ฝ์
: O(logN)
โ ์ญ์ (์ฐ์ ์์): O(logN)
โ ์กฐํ: O(1)
import java.util.PriorityQueue;
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((a, b) -> b - a);
priorityQueue.offer(1);
priorityQueue.offer(2);
priorityQueue.offer(3);
System.out.println(priorityQueue); // Output: [3, 2, 1]
System.out.println(priorityQueue.peek()); // Output: 3
priorityQueue.offer(4);
System.out.println(priorityQueue); // Output: [4, 3, 1, 2]
System.out.println(priorityQueue.poll()); // Output: 4
System.out.println(priorityQueue); // Output: [3, 2, 1]
Heap(ํ)
โ ๋ถ๋ชจ๊ฐ ํญ์ ์์๋ณด๋ค (์๊ฑฐ๋/ํฌ๊ฑฐ๋) ๊ฐ์ ํ์ ํน์ฑ์ ๋ง์กฑํ๋ ํธ๋ฆฌ ๊ธฐ๋ฐ์ ์๋ฃ๊ตฌ์กฐ
โ ์์ ์ด์งํธ๋ฆฌ
โ ๋ฃจํธ๋ ํญ์ ์ต์/์ต๋๊ฐ
โ ์ฝ์
: O(logN)
โ ์ถ์ถ: O(logN) (๋จ์ํ ๋ฃจํธ ๋
ธ๋ ์ถ์ถ ์์ฒด๋ O(1)์ด๋ ์ถ์ถ ํ ๋ค์ ๊ท ํ์ ์ ์งํ๊ธฐ์ O(logN))
import java.util.Arrays;
class MaxHeap {
private int[] heap;
private int size;
MaxHeap(int capacity) {
heap = new int[capacity];
size = 0;
}
int getParentIndex(int i) { return (i - 1) / 2; }
int getLeftChildIndex(int i) { return 2 * i + 1; }
int getRightChildIndex(int i) { return 2 * i + 2; }
boolean hasParent(int i) { return getParentIndex(i) >= 0; }
boolean hasLeftChild(int i) { return getLeftChildIndex(i) < size; }
boolean hasRightChild(int i) { return getRightChildIndex(i) < size; }
int parent(int i) { return heap[getParentIndex(i)]; }
int leftChild(int i) { return heap[getLeftChildIndex(i)]; }
int rightChild(int i) { return heap[getRightChildIndex(i)]; }
void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
void ensureCapacity() {
if (size == heap.length) {
heap = Arrays.copyOf(heap, 2 * heap.length);
}
}
void insert(int item) {
ensureCapacity();
heap[size] = item;
size++;
siftUp(size - 1);
}
void siftUp(int i) {
while (hasParent(i) && parent(i) < heap[i]) {
int parentIndex = getParentIndex(i);
swap(parentIndex, i);
i = parentIndex;
}
}
int extractMax() {
int max = heap[0];
heap[0] = heap[size - 1];
size--;
siftDown(0);
return max;
}
void siftDown(int i) {
while (hasLeftChild(i)) {
int largerChildIndex = getLeftChildIndex(i);
if (hasRightChild(i) && rightChild(i) > leftChild(i)) {
largerChildIndex = getRightChildIndex(i);
}
if (heap[i] >= heap[largerChildIndex]) {
break;
}
swap(i, largerChildIndex);
i = largerChildIndex;
}
}
public static void main(String[] args) {
MaxHeap heap = new MaxHeap(10);
heap.insert(10);
heap.insert(5);
heap.insert(15);
heap.insert(30);
heap.insert(20);
System.out.println(heap.extractMax()); // 30
System.out.println(heap.extractMax()); // 20
System.out.println(heap.extractMax()); // 15
System.out.println(heap.extractMax()); // 10
System.out.println(heap.extractMax()); // 5
}
}
5. Hash
Hash (Function)
โ ์์์ ๊ธธ์ด๋ฅผ ๊ฐ๋ ์์์ ๋ฐ์ดํฐ๋ฅผ ๊ณ ์ ๋ ๊ธธ์ด์ ๋ฐ์ดํฐ๋ก ๋งคํํ๋ ๋จ๋ฐฉํฅ ํจ์
Hash Collision
โ ๋ ๊ฐ ์ด์์ ํค(ํด์ ํจ์์ ์ ๋ ฅ๊ฐ)๊ฐ ํด์ ํ ์ด๋ธ์ ๋์ผํ ์ธ๋ฑ์ค(ํด์ ํจ์์ ์ถ๋ ฅ๊ฐ)์ ๋งคํ๋๋ ํ์
โ ์์ธ
- ๋น๋๊ธฐ์ง ์๋ฆฌ: n+1๊ฐ์ ๋ฌผ๊ฑด์ n๊ฐ์ ์์์ ๋ฃ์ ๋ ์ ์ด๋ ์ด๋ ํ ์์์๋ ๋ ๊ฐ ์ด์์ ๋ฌผ๊ฑด์ด ๋ค์ด ์๋ค๋ ์๋ฆฌ
- ์์ผ ๋ฌธ์ : ์ฌ๋ฌ ์ฌ๋์ด ๋ชจ์์ ๋ ์์ผ์ด ๊ฐ์ 2๋ช
์ด ์กด์ฌํ ํ๋ฅ ์? (23๋ช
-> 50%, 57๋ช
-> 99%)
- ์ถฉ๋์ ์๊ฐ๋ณด๋ค ์ฝ๊ฒ ์ผ์ด๋๋ค!
โ ํด๊ฒฐ
- Chaining: ํด์ ํ ์ด๋ธ์ ์ธ๋ฑ์ค๊ฐ ํด๋น ์ธ๋ฑ์ค์ ์ฐ๊ฒฐ๋ ํญ๋ชฉ๋ค์ ๋ด์ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ๊ฐ๋ฆฌํจ๋ค (java)
- Open Addressing: ์ถฉ๋ ๋ฐ์ ์ ํ์ฌ๋ฅผ ํตํด ๋ค์ ๋น๊ณต๊ฐ์ ์ฐพ๋๋ค (Python)
HashMap / HashTable
โ HashMap / HashTable: Key(ํค) - Value(๊ฐ) ๋งคํ์ด ๊ฐ๋ฅํ ์๋ฃ๊ตฌ์กฐ
โ ์กฐํ: ํ๊ท O(1) / ์ต์ O(N)
import java.util.HashMap;
public class Example {
public static void main(String[] args) {
// Creating a HashMap
HashMap<String, Integer> map = new HashMap<>();
// Adding key-value pairs to the map
map.put("John", 25);
map.put("Jane", 30);
map.put("Jim", 35);
// Retrieving values from the map
System.out.println("Age of John: " + map.get("John"));
System.out.println("Age of Jane: " + map.get("Jane"));
System.out.println("Age of Jim: " + map.get("Jim"));
}
}
// Age of John: 25
// Age of Jane: 30
// Age of Jim: 35
6. Graph
โ ๋ ธ๋(node/vertex)์ ๊ฐ์ (edge)์ผ๋ก ๊ตฌ์ฑ๋ ์๋ฃ์ ์งํฉ
โ ๋ ธ๋(Node): ์ ๋ณด์ ๋จ์, ๊ฐ์ (Edge): ๋ ธ๋ ๊ฐ์ ๊ด๊ณ
โ ์ธ์ ๋ฆฌ์คํธ / ์ธ์ ํ๋ ฌ๋ก ๊ตฌํ
// ์ธ์ ํ๋ ฌ
N = Integer.parseInt(br.readLine()); // ๋
ธ๋
M = Integer.parseInt(br.readLine()); // ๊ฐ์
arr = new int[N+1][N+1]
for(int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int node1 = Integer.parseInt(st.nextToken());
int node2 = Integer.parseInt(st.nextToken());
arr[node1][node2] = 1;
arr[node2][node1] = 1;
}
// ์ธ์ ๋ฆฌ์คํธ
N = Integer.parseInt(br.readLine()); // ๋
ธ๋
M = Integer.parseInt(br.readLine()); // ๊ฐ์
LinkedList<Integer>[] adjList = new LinkedList[N + 1];
for (int i = 0; i <= N; i++) {
adjList[i] = new LinkedList<Integer>();
}
for (int i = 0; i < M; i++) {
int node1 = Integer.parseInt(st.nextToken());
int node2 = Integer.parseInt(st.nextToken());
adjList[node1].add(node2);
adjList[node2].add(node1);
}
7. Tree
Tree
โ Tree: ์ฌ์ดํด์ด ์๋ ์ฐ๊ฒฐ ๊ทธ๋ํ
โ ์ฉ์ด
- ๋
ธ๋(node): ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๊ธฐ๋ณธ ์์
- ๋ฃจํธ ๋ ธ๋(root node/root): ํธ๋ฆฌ์์ ๋ถ๋ชจ๊ฐ ์๋ ์ต์์ ๋ ธ๋, ํธ๋ฆฌ์ ์์์
- ๋ถ๋ชจ ๋ ธ๋(parent node): ๋ฃจํธ ๋ ธ๋ ๋ฐฉํฅ์ผ๋ก ์ง์ ์ฐ๊ฒฐ๋ ๋ ธ๋
- ์์ ๋ ธ๋(child node): ๋ฃจํธ ๋ ธ๋ ๋ฐ๋๋ฐฉํฅ์ผ๋ก ์ง์ ์ฐ๊ฒฐ๋ ๋ ธ๋
- ํ์ ๋ ธ๋(siblings node): ๊ฐ์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๊ฐ๋ ๋ ธ๋๋ค
- ๋ฆฌํ ๋ ธ๋(leaf node/leaf): ๋ฃจํธ ๋ ธ๋๋ฅผ ์ ์ธํ ์ฐจ์๊ฐ 1์ธ ์ ์ (์์์ด ์๋ ๋ ธ๋)
- ๊ฒฝ๋ก(path): ํ ๋ ธ๋์์ ๋ค๋ฅธ ํ ๋ ธ๋์ ์ด๋ฅด๋ ๊ธธ ์ฌ์ด์ ์๋ ๋ ธ๋๋ค์ ์์
- ๊ธธ์ด(length): ์ถ๋ฐ ๋ ธ๋์์ ๋์ฐฉ ๋ ธ๋๊น์ง ๊ฑฐ์น๋ ๊ฐ์ ์ ๊ฐ์
- ๊น์ด(depth): ๋ฃจํธ ๊ฒฝ๋ก์ ๊ธธ์ด
- ๋ ๋ฒจ(level): ๋ฃจํธ ๋ ธ๋(level=0)๋ถํฐ ๋ ธ๋๊น์ง ์ฐ๊ฒฐ๋ ๊ฐ์ ์์ ํฉ
- ๋์ด(height): ๊ฐ์ฅ ๊ธด ๋ฃจํธ ๊ฒฝ๋ก์ ๊ธธ์ด
- ์ฐจ์(degree): ๊ฐ ๋ ธ๋์ ์์์ ๊ฐ์
- ํธ๋ฆฌ์ ์ฐจ์(degree of tree): ํธ๋ฆฌ์ ์ต๋ ์ฐจ์
- ํฌ๊ธฐ(size): ๋ ธ๋์ ๊ฐ์
Tree vs Graph
โ ํธ๋ฆฌ๋ ์ํ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์๋๋ค!
์ด์งํธ๋ฆฌ (Binary Tree)
โ ๋ชจ๋ ๋ ธ๋์ ์ฐจ์๊ฐ 2 ์ดํ์ธ ํธ๋ฆฌ
โ ๋ค์ง ํธ๋ฆฌ์ ๋นํด ํจ์ฌ ๊ฐ๊ฒฐํ๊ณ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ธฐ ์ฌ์์ ๋ง์ด ์ด๋ค!
โ ์ด์งํธ๋ฆฌ์ ์ข ๋ฅ
์ด์ง ํ์ ํธ๋ฆฌ (Binary Search Tree)
โ ๋ ธ๋์ ์ผ์ชฝ ๊ฐ์ง์๋ ๋ ธ๋์ ๊ฐ๋ณด๋ค ์์ ๊ฐ๋ค๋ง ์๊ณ , ์ค๋ฅธ์ชฝ ๊ฐ์ง์๋ ํฐ ๊ฐ๋ค๋ง ์๋๋ก ๊ตฌ์ฑ๋ ์ด์งํธ๋ฆฌ
โ (์ด์์ ์ธ ์ํฉ์์) ํ์/์ฝ์ /์ญ์ : O(logN)
- ์ต์ ์ ๊ฒฝ์ฐ(ํธํฅ): O(N) (ex: 1~100)
ํธ๋ฆฌ์ ์ํ
โ ์ค์ ์ํ(in-order traversal): ์ผ์ชฝ ์์, ์์ , ์ค๋ฅธ์ชฝ ์์ ์์๋ก ๋ฐฉ๋ฌธํ๋ ์ํ ๋ฐฉ๋ฒ
- ์ด์ง ํ์ ํธ๋ฆฌ ์ค์ ์ํ ์ ์ ๋ ฌ๋ ๊ฒฐ๊ณผ ๋ฐํ
โ ์ ์ ์ํ(pre-order traversal): ์์ , ์ผ์ชฝ ์์, ์ค๋ฅธ์ชฝ ์์ ์์๋ก ๋ฐฉ๋ฌธํ๋ ์ํ ๋ฐฉ๋ฒ
โ ํ์ ์ํ(post-order traversal): ์ผ์ชฝ ์์, ์ค๋ฅธ์ชฝ ์์, ์์ ์์๋ก ๋ฐฉ๋ฌธํ๋ ์ํ ๋ฐฉ๋ฒ
โ ๋ ๋ฒจ ์์ ์ํ(level-order traversal): ๋ ๋ฒจ ์์๋ก ์ํ(BFS)
8. Advanced Tree
AVL Tree
โ ์๊ฐ ๊ท ํ ์ด์ง ํ์ ํธ๋ฆฌ
โ ์ผ๋ฐ์ ์ธ ์ด์ง ํ์ ํธ๋ฆฌ์ ํธํฅ์ฑ์ ๋ณด์ํ๊ธฐ ์ํด ์ฝ์ /์ญ์ ์๋ง๋ค ๊ท ํ์ ๋ง์ถฐ์ค๋ค (ํธ๋ฆฌ ํ์ )
โ ์ค๋ฅธ์ชฝ ํธ๋ฆฌ์ ์ผ์ชฝ ํธ๋ฆฌ์ ๋์ด ์ฐจ๊ฐ 1 ์ดํ
โ ๋ชจ๋ ์ํฉ์์ ํ์/์ฝ์ /์ญ์ : O(logN)
Red-Black Tree
โ ์๊ฐ ๊ท ํ ์ด์ง ํ์ ํธ๋ฆฌ
โ ์กฐ๊ฑด
- ๋ชจ๋ ๋ ธ๋๋ red or black
- ๋ฃจํธ ๋ ธ๋๋ black
- ์์์ด ์๋ ๋ ธ๋๋ Null Leaf Node (NIL)๋ผ๊ณ ํ๋ค
- ๋ชจ๋ NIL์ black
- red์ ์์์ ์ธ์ ๋ black -> red๋ ์ฐ์์ผ๋ก ๋์ฌ ์ ์๋ค! (black์ ๊ฐ๋ฅ)
- ์์์ ํ ๋ ธ๋์์ null leaf node๊น์ง ๋๋ฌํ๋ ๋ชจ๋ ๊ฒฝ๋ก์๋ null leaf node๋ฅผ ์ ์ธํ๊ณ ํญ์ ๊ฐ์ ์์ ๋ธ๋ ๋ ธ๋ ์กด์ฌ
โ ๋ชจ๋ ์ํฉ์์ ํ์/์ฝ์ /์ญ์ : O(logN)
โ ์ด์งํ์ํธ๋ฆฌ ์ค์ ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ!
'โญ Personal_Study > CS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
CS ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ - ์ด์์ฒด์ 2 (0) | 2023.03.03 |
---|---|
CS ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ - ์ด์์ฒด์ 1 (3) | 2023.03.02 |
CS ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ - ๋คํธ์ํฌ (0) | 2023.02.23 |
CS ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ - ์๊ณ ๋ฆฌ์ฆ (0) | 2023.02.19 |
CS ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ - ํ๋ก๊ทธ๋๋ฐ ์ผ๋ฐ (0) | 2023.02.06 |
๋๊ธ