: 임의의 크기를 가진 데이터를 고정된 데이터의 크기로 변환시키는 것.
특정한 배열의 인덱스나 위치를 입력하고자 하는 데이터값을 이용해 저장하거나 찾을 수 있다.
해시를 이용하면 즉시 저장하거나 찾고자 하는 위치를 참조할 수 있으므로 더욱 빠른 속도로 처리할 수 있다.
: 키-값 쌍의 데이터를 배열에 저장할 때, 키값을 직접적으로 배열의 인덱스로 사용하는 방법.
똑같은 키가 없다고 가정할 때 찾고자 하는 데이터의 키만 알고 있으면 즉시 위치를 찾을 수 있으므로 crud 모두 선형시간 (O(1)) 으로 처리할 수 있다.
다만, 키 값의 최대 크기만큼 배열이 할당되어 주의가 필요하다.
: 키-값 쌍에서 키 값을 테이블에 저장할 때, 키값을 함수로 이용해 계산을 수행한 후, 그 결과값을 배열의 인덱스로 사용하여 저장하는 방식.
여기서 키값을 계산하는 함수는 해쉬함수다.
해쉬함수는 입력으로 키를 받아 0부터 배열의 크기-1 사이의 값을 출력한다.
해쉬에 대한 첫 정의대로 임의의 숫자를 배열의 크기만큼으로 변환시킨 것.
이 경우 k값이 h(k)로 해쉬되었다고 하며, h(k)는 k의 해쉬값이라고 한다.
: 모든 데이터(키-값)를 테이블에 저장하는 방법.
장점 - 데이터를 모두 직접 읽어와서 포인터를 사용하지 않는다. 그로인해 발생할 수 있는 오버헤드를 방지할 수 있다.
포인터가 필요없어 구현이 용이해지고, 포인터 접근에 필요한 시간이 없어 큰 성능이 향상된다.
: 데이터를 쌓아놓은 자료구조. 선입후출(LIFO). 먼저 들어오고 나중에 들어온게 나간다.
ex. 뒤로가기
: 데이터를 쌓아놓은 자료구조. 선입선출(FIFO). 먼저 들어오고 먼저 들어온게 나간다.
ex. 줄서기
: 완전 이진 트리의 일종. 여러 개의 값들 중에서 최댓값이나 최솟값을 빠르게 찾아내도록 만들어진 자료구조.
일종의 반정렬 상태(느슨한 정렬 상태)를 유지한다.
힙으로 우선순위 큐를 구현할 수 있다.
힙을 저장하는 표준적인 자료구조 -> 배열
: 원소들을 번호순이나 사전 순서와 같이 일정한 순서대로 열거하는 알고리즘.
효율적인 정렬은 탐색이나 병합 알고리즘처럼 다른 알고리즘을 최적화하는데 중요하다.
데이터의 정규화나 이미있는 결과물을 생성하는 데 흔히 유용하게 쓰인다.
만족해야 할 두 조건
1. 출력은 비 내림차순이다. (각각의 원소가 전 순서 원소에 비해 이전의 원소보다 작지 않은 순서)
2. 출력은 입력을 재배열하여 만든 순열이다.
: 작은 데이터에 효율적. 큰 데이터에는 비효율적.
삽입 정렬, 선택 정렬
: 다양한 수정이 수반되는 실생활 데이터를 기준으로 랜덤 데이터에 점근적으로 효율적이다.
평균 시간 복잡도 - O(NlogN)
합병 정렬, 힙 정렬, 퀵 정렬, 셸 정렬
거품 정렬, 빗질 정렬
계수 정렬, 버킷 정렬, 기수 정렬
: 가능한 모든 경우의 수를 다 체크해서 정답을 찾는 방법.
-> 무식하게 가능한거 다 해볼거야!
a.k.a. Brute Force
직관적이어서 이해하기 쉽고, 문제의 정확한 결과값을 얻어낼 수 있는 가장 호가실하며 기초적인 방법.
부분적인 최적해가 전체적인 최적해가 된다.
: 미래를 생각하지 않고 각 단계에서 가장 최선의 선택을 하는 기법. 각 단계에서 최선의 선택을 한 것이 전체적으로 최선이길 바란다. 모든 경우는 아니지만 이 방법이 통하는 경우가 있다.
DP 사용 시 지나치게 많은 일을 한다는 것에 착안하여 고안된 알고리즘. DP와 같이 쓰이며 서로 보완하는 개념이다.
a.k.a 탐욕 알고리즘, 그리디 알고리즘, 욕심쟁이 알고리즘
-> 한 강의실에서 여러 개의 수업을 하려고 할 때, 한 번에 가장 많은 수업을 할 수 있는 경우 고르기
-> 무게가 초과하기 전까지 물건을 쪼개가며 가장 많은 짐을 넣는 방법
불필요한 계산을 줄이고, 효율적으로 최적해를 찾아야만 풀리는 문제
: 복잡한 문제를 간단한 여러 개의 문제로 나누어 푸는 방법. 부분 문제 반복과 최적 부분 구조를 가지고 있는 알고리즘을 일반적인 방법에 비해 더욱 적은 시간 내에 풀 때 사용한다.
각 하위 문제의 해결을 계산한 뒤, 그 해결책을 저장하여 후에 같은 하위 문제가 나왔을 경우 저장된 값을 불러와 사용한다. -> 계산 횟수가 줄어든다.
하위 문제의 수가 기하급수적으로 증가할 때 유용하다.
최단 경로 문제, 행렬의 제곱 문제 등의 최적화에 사용된다.
동적 계획법은 그리디 알고리즘에 비해 시간적으로는 효율적이지 못할 수는 있어도, 그 결과에 대해서는 효율적인 값을 구할 수가 있다.
: 루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
한 방향으로 갈 수 있을 때까지 계속 가다가 더이상 갈 수 없게 되면 다시 가장 가까운 갈림길로 돌아와 이곳부터 다른 방향으로 다시 탐색을 진행하는 방법과 유사하다.
깊게 탐색.
모든 노드를 방문해야 할 때 사용한다.
bfs보다 간단한다.
단순 검색 속도는 bfs보다 느리다.
현재 노드와 인접한 노드를 꼬리에 꼬리를 물어 순회한다.
더 갈 수 없을 경우, 이전 노드로 돌아와 위와 같이 순회한다.
순환 호출 이용
명시적인 스택 사용 (방문한 정점들을 스택에 저장하였다 꺼내서 작업한다.)
: 루트 노드(혹은 다른 임의의 노드)에서 시작해서 인접한 노드를 먼저 탐색하는 방법
시작 정점으로부터 가까운 정점을 먼저 모두 방문하고, 멀리 떨어져 있는 정점을 나중에 방문하는 순회 방법
넓게 탐색
두 노드 사이의 최단 경로, 임의의 경로를 찾고 싶을 때 사용한다.
dfs보다 좀 더 복잡하다.
직관적이지 않은 면이 있다.
재귀적으로 동작하지 않는다.
어떤 노드를 방문했는지 여부를 반드시 검사해야 한다. (안하면 무한루프)
선입선출을 원칙으로 탐색하는 큐를 사용한다.
prim, dijkstra 알고리즘과 유사하다.
: 탐색 기법중에 하나. 원하는 탐색 부위를 두 부분으로 분할하여 찾는 방식. 원래의 전부를 탐색하는 탐색 속도에 비해 빠르다.
전체 검색: O(N)
이분 탐색: O(logN)
: 정점(vertex)과 간선(edge)으로 이루어진 자료구조. 정점간의 관계를 표현하는 조직도.
-> 트리도 그래프의 일종이다.
정점마다 간선이 없을 수도 있고 있을 수도 있다.
루트노드, 부모와 자식의 개념이 없다.
이 그래프를 순회하는 방식을 잘 알아야 한다.
인접 행렬(Adjacency Matrix), 인접 리스트(Adjacency List)
: 그래프의 노드를 2차원 배열로 만든 것.
: 그래프의 노드들을 리스트로 표현한 것. 주로 정점의 리스트 배열을 만들어 관계를 설정해줌으로써 구현한다.
무방향 그래프
: 두 정점을 연결하는 간선에 방향이 없는 그래프
방향 그래프
: 두 정점을 연결하는 간선에 방향이 존재하는 그래프. 간선의 방향으로만 이동할 수 있다.
가중치 그래프
: 두 정점을 이동할 때 비용이 드는 그래프
완전 그래프
: 모든 정점이 간선으로 연결되어 있는 그래프