기본 콘텐츠로 건너뛰기

Median값 찾기 알고리즘

출처 : https://o-tantk.github.io/posts/finding-median/
(감사합니다!)

중앙값 찾기

중앙값은 정렬된 배열에서 찾아야 한다. 가장 먼저 정렬을 수행해야 한다.정렬 후엔, 단순히 배열 크기의 절반에 해당하는 인덱스에 접근해 반환하면 된다.

실시간으로 중앙값(Running Median) 찾기
수행 속도가 훨씬 빠른, 추가/삭제가 정렬과 함께 이루어지는 자료 구조를 이용, Heap
알고리즘
  • Max heap은 최대값에 바로 접근할 수 있다.
  • Min heap은 최소값에 바로 접근할 수 있다.
Heap의 두 성질 이용해, 중앙값보다 작은 값들은 Max heap에, 중앙값보다 큰 값들은 Min heap에 저장하는 방식으로 중앙값을 찾는 알고리즘을 구현할 수 있다. 아래의 상황을 보자.첫 번째 단계먼저, 작은 값과 큰 값을 나눌 기준이 필요하다. 중앙값이 아니라 굳이 기준이라 표현한 이유는, 개수가 짝수일 때를 고려해서이다.
기준은 어차피 가운데에 있으니, 변수를 따로 만들 필요 없이 Max heap 또는 Min heap에 포함시키면 된다. 여기선 Max heap을 이용했다.두 번째 단계첫 번째 입력은 별 수 없이 기준이 된다. 홀수개이므로 중앙값은 3이다.
나머지는 기준보다 작다면 Max heap에, 크다면 Min heap에 넣는다. 그리고, Max heap과 Min heap의 크기가 균형되도록 조절한다. 다만, 기준을 고려해 기준을 가진쪽이 하나는 더 클 수 있도록 허용한다.세 번째 단계네 번째 단계2는 기준보다 작으니 Max heap에 넣지만 균형을 맞추기 위해 Max heap의 최대값을 이동시킨다. 짝수개이므로 중앙값은 2와 3의 평균이다.다섯 번째 단계여섯 번째 단계4는 기준보다 크니 Min heap에 넣지만 균형을 맞추기 위해 Min heap의 최소값을 이동시킨다. 홀수개이므로 중앙값은 3이다.일곱 번째 단계여덟 번째 단계1은 기준보다 작으니 Max heap에 넣지만 균형을 맞추기 위해 Max heap의 최대값을 이동시킨다. 짝수개이므로 중앙값은 2와 3의 평균이다.
입력이 들어올 때마다 한 번의 데이터 이동만으로 실시간으로 중앙값을 찾고 있다. Heap의 시간복잡도가 O(log N)이므로 최악의 경우라도 ‘삽입 + 삭제 + 삽입’의 O(3 log N)의 성능을 보인다.

댓글

이 블로그의 인기 게시물

Dijkstra 알고리즘과 실행시간(Priority Queue를 사용하는 이유)

정의 어떤 변도 음수 가중치를 갖지 않는 유향 그래프에서 주어진 출발점과 도착점 사이의 최단 경로 문제를 푸는 알고리즘 알고리즈 개요 데이크스트라 알고리즘은 각각의 꼭짓점 v에 대해 s에서 v까지의 최단 거리 d[v]를 저장하면서 작동한다. 알고리즘의 시작 시에 d[s]=0이고, s가 아닌 다른 모든 꼭짓점 v에 대해서는 d[v]=∞로 놓아 다른 꼭짓점에 대해서는 아직 최단 경로를 모른다는 사실을 표시한다. 알고리즘이 종료되었을 때 d[v]는 s에서 v까지의 최단 경로의 거리를 나타내게 되고, 만약 경로가 존재하지 않으면 거리는 여전히 무한대로 남는다. 데이크스트라 알고리즘은 변 경감(edge relaxation)이라고 불리는 기본 연산을 바탕으로 한다. s에서 u까지의 최단 경로(d[u])를 이미 알고 있고, u에서 v까지 길이가 w(u,v)인 변 (u, v)가 존재할 때, s에서 v까지의 최단 경로는 u까지의 최단 경로에 변 (u, v)를 추가함으로써 얻을 수 있다. 이 경로의 비용은 d[u]+w(u, v)가 되며, 이 비용이 현재의 d[v] 값보다 낮으면 d[v]를 새로운 값으로 바꾼다. 경감 연산은 모든 변 (u, v)에 대해 한번씩 경감이 적용되어 모든 d[v]가 최단 경로의 비용을 나타내게 되었을 때 끝난다. 실행시간 개의 변과  {\displaystyle n} 개의  꼭짓점 을 가진  그래프 에 대해  대문자 O 표기법 으로 데이크스트라 알고리즘의 실행시간을 나타낼 수 있다. 가장 간단한 구현으로,  Q 의 집합을  연결 리스트 나  배열  구조로 구현하고 Extract-Min(Q) 함수를 단순한  선형 탐색 으로 구현했을 때 실행 시간은  {\displaystyle O(n^{2})}  시간이 된다. 만약 희소 그래프(sparse graph), 즉  {\displaystyle n^{2}} 보다 훨씬 작은 개수의 변만을 갖는 그래프에 대해서는,  인접 리스트 와 바이너리  힙  또는  피보나치 힙 으로 구현한  우선순위 큐 를 이용해 데이크스트라 알