맨위로가기

배처 홀짝 병합 정렬

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

배처 홀짝 병합 정렬은 2의 거듭제곱 길이를 가진 리스트를 정렬하는 알고리즘이다. 파이썬으로 구현된 예시 코드를 통해 작동 방식을 확인할 수 있으며, 병합 정렬 방식을 사용한다.

더 읽어볼만한 페이지

  • 정렬 알고리즘 - 합병 정렬
    합병 정렬은 분할 정복 알고리즘을 사용하여 리스트를 재귀적으로 분할하고 정렬된 부분 리스트를 병합하는 비교 기반 정렬 알고리즘으로, O(n log n)의 시간 복잡도를 가지며 안정 정렬에 속하고 연결 리스트 정렬 및 외부 정렬에 유용하다.
  • 정렬 알고리즘 - 퀵 정렬
    퀵 정렬은 토니 호어가 개발한 분할 정복 방식의 효율적인 정렬 알고리즘으로, 피벗을 기준으로 리스트를 분할하여 정렬하는 과정을 재귀적으로 반복하며 다양한 최적화 기법과 변형이 존재한다.
배처 홀짝 병합 정렬
알고리즘 정보
종류정렬 알고리즘
자료 구조배열
최적 시간 복잡도 (병렬)O(log²(n))
평균 시간 복잡도 (병렬)O(log²(n))
시간 복잡도 (병렬)O(log²(n))
공간 복잡도 (비병렬)O(n log²(n))
최적화 여부아니오
고안자켄 배처
참고 문헌"Sorting Networks and their Applications", Ken Batcher, Proceedings of the April 30--May 2, 1968, spring joint computer conference on - AFIPS '68 (Spring), Association for Computing Machinery, pages 307–314, 1968, 원문 보기
"Chapter 46. Improved GPU Sorting", GPU Gems 2
8개 입력을 받은 홀-짝 병합 정렬망의 시각화
8개 입력을 받은 홀-짝 병합 정렬망의 시각화

2. 알고리즘

배처 홀짝 병합 정렬은 병합 정렬의 일종으로, 재귀적인 방식으로 리스트를 정렬한다. 기본적인 아이디어는 리스트를 반으로 나누어 각각 정렬한 다음, '홀짝 병합(odd-even merge)'이라는 특별한 방식으로 두 정렬된 부분을 합치는 것이다.

이 알고리즘은 비교 및 교환(compare-and-swap) 연산을 기반으로 한다. 두 요소의 위치를 비교하여 필요한 경우 서로 바꾸는 간단한 연산이다.

다음은 파이썬으로 구현된 배처 홀짝 병합 정렬 알고리즘의 예시이다. 입력 리스트 `x`는 0부터 인덱싱된다고 가정한다.



def compare_and_swap(x, a, b):

""" 배열 x의 a와 b 인덱스 요소를 비교하여, x[a] > x[b] 이면 두 요소의 위치를 바꾼다. """

if x[a] > x[b]:

x[a], x[b] = x[b], x[a]

def oddeven_merge(x, lo, hi, r):

""" 홀짝 병합을 수행하는 함수. lo부터 hi까지 r 간격으로 요소를 비교하고 교환한다. """

step = r * 2

if step < hi - lo:

# 병합 단계를 재귀적으로 더 작은 부분 문제로 나눈다.

oddeven_merge(x, lo, hi, step) # 짝수 인덱스 부분 병합 (간격 step)

oddeven_merge(x, lo + r, hi, step) # 홀수 인덱스 부분 병합 (간격 step)

# 부분 병합 결과를 합친다. (간격 r)

for i in range(lo + r, hi - r, step):

compare_and_swap(x, i, i + r)

else:

# 가장 작은 단위의 병합 (요소 2개 비교, 간격 r)

compare_and_swap(x, lo, lo + r)

def oddeven_merge_sort_range(x, lo, hi):

""" 배열 x의 lo부터 hi까지 구간을 정렬한다. (lo와 hi 인덱스 포함) """

if (hi - lo) >= 1:

# 구간에 요소가 1개 이상 있을 경우

# 구간을 반으로 나누어 각각 재귀적으로 정렬한다.

mid = lo + ((hi - lo) // 2) # 중간 인덱스 계산 (정수 나눗셈)

oddeven_merge_sort_range(x, lo, mid) # 앞부분 정렬

oddeven_merge_sort_range(x, mid + 1, hi) # 뒷부분 정렬

# 정렬된 두 부분을 홀짝 병합한다. (초기 간격 1)

oddeven_merge(x, lo, hi, 1)

def oddeven_merge_sort(x):

""" 입력 리스트 x 전체를 배처 홀짝 병합 정렬한다. """

oddeven_merge_sort_range(x, 0, len(x)-1)

# 실행 예시

data = [2, 4, 3, 5, 6, 1, 7, 8]

oddeven_merge_sort(data)

# 정렬 후 data: [1, 2, 3, 4, 5, 6, 7, 8]



위 코드에서 `oddeven_merge_sort_range` 함수는 리스트를 재귀적으로 반으로 나누어 정렬하고, `oddeven_merge` 함수를 호출하여 정렬된 두 부분을 병합한다. `oddeven_merge` 함수는 홀수 위치와 짝수 위치의 요소들을 비교하는 과정을 재귀적으로 반복하여 전체 구간을 정렬된 상태로 만든다.

비교 및 정렬할 요소의 인덱스를 계산하는 구체적인 방법은 의사 코드 섹션에서 자세히 설명한다. 파트너 노드 인덱스를 재귀 없이 계산하는 방법도 존재한다.[4]

2. 1. 의사 코드

다음은 배처 홀짝 병합 정렬 알고리즘의 의사 코드이다. 입력 배열은 0부터 n-1까지 인덱싱된다고 가정한다.



# 참고: 입력 시퀀스는 0부터 (n-1)까지 인덱싱됩니다.

for p = 1, 2, 4, 8, ... # p < n인 동안

for k = p, p/2, p/4, p/8, ... # k >= 1인 동안

for j = mod(k,p) to (n-1-k) with a step size of 2k

for i = 0 to k-1 with a step size of 1

if floor((i+j) / (p*2)) == floor((i+j+k) / (p*2))

# 요소 (i+j)와 (i+j+k)를 비교하고 정렬합니다.

compare_and_swap(sequence[i+j], sequence[i+j+k])



비교 및 정렬할 요소의 인덱스를 계산하는 데에는 다양한 재귀반복 방식이 사용될 수 있다. 다음은 n개의 요소를 정렬하기 위한 인덱스를 생성하는 반복 기법 중 하나이다.



# 참고: 입력 시퀀스는 0부터 (n-1)까지 인덱싱됩니다.

for p = 1, 2, 4, 8, ... # p < n인 동안

for k = p, p/2, p/4, p/8, ... # k >= 1인 동안

for j = mod(k,p) to (n-1-k) with a step size of 2k

for i = 0 to min(k-1, n-j-k-1) with a step size of 1

if floor((i+j) / (p*2)) == floor((i+j+k) / (p*2))

# 요소 (i+j)와 (i+j+k)를 비교하고 정렬합니다.

compare_and_swap(sequence[i+j], sequence[i+j+k])



파트너 노드 인덱스를 재귀 없이 계산하는 것도 가능하다.[4]

3. 구현 예시

배처 홀짝 병합 정렬 알고리즘은 다양한 프로그래밍 언어로 구현될 수 있다. 대표적인 예시 중 하나로 파이썬을 이용한 구현이 있으며, 이는 입력으로 길이가 2의 거듭제곱인 리스트를 받아 정렬된 리스트를 반환하는 방식으로 동작한다.

3. 1. Python

다음은 Python으로 구현된 배처 홀짝 병합 정렬 코드이다. 이 코드는 입력으로 길이가 2의 거듭제곱인 리스트를 받아 정렬된 리스트를 반환한다.



def compare_and_swap(x, a, b):

"""리스트 x의 a, b 인덱스 요소를 비교 후 교환"""

if x[a] > x[b]:

x[a], x[b] = x[b], x[a]

def oddeven_merge(x, lo, hi, r):

"""홀짝 병합 수행 (재귀 호출 가능)"""

step = r * 2

if step < hi - lo:

oddeven_merge(x, lo, hi, step)

oddeven_merge(x, lo + r, hi, step)

# 병합 단계: r 간격의 요소들을 비교/교환

for i in range(lo + r, hi - r, step):

compare_and_swap(x, i, i + r)

else:

# 기본 단계: 인접한 요소 비교/교환

compare_and_swap(x, lo, lo + r)

def oddeven_merge_sort_range(x, lo, hi):

""" 리스트 x의 lo부터 hi까지 구간 정렬 (lo, hi 인덱스 포함)"""

if (hi - lo) >= 1:

# 구간에 요소가 1개 이상일 경우

# 구간을 절반으로 나누어 각각 재귀 정렬 후 병합

mid = lo + ((hi - lo) // 2) # 정수 나눗셈

oddeven_merge_sort_range(x, lo, mid)

oddeven_merge_sort_range(x, mid + 1, hi)

oddeven_merge(x, lo, hi, 1)

def oddeven_merge_sort(x):

"""리스트 x 전체를 배처 홀짝 병합 정렬"""

oddeven_merge_sort_range(x, 0, len(x)-1)

# 실행 예시

data = [2, 4, 3, 5, 6, 1, 7, 8]

oddeven_merge_sort(data)

# 정렬 후 data: [1, 2, 3, 4, 5, 6, 7, 8]


참조

[1] 간행물 Proceedings of the April 30--May 2, 1968, spring joint computer conference on - AFIPS '68 (Spring) Association for Computing Machinery
[2] 서적 The Art of Computer Programming Addison-Wesley
[3] 웹사이트 Chapter 46. Improved GPU Sorting https://developer.nv[...]
[4] 웹사이트 Sorting network from Batcher's Odd-Even merge: partner calculation https://gist.github.[...] Renat Bekbolatov 2015-05-07
[5] 서적 The Art of Computer Programming Addison-Wesley
[6] URL https://developer.nv[...]
[7] 인용 Sorting Networks and their Applications http://www.cs.kent.e[...] Association for Computing Machinery
[8] 서적 The Art of Computer Programming Addison-Wesley
[9] 웹인용 Chapter 46. Improved GPU Sorting https://developer.nv[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com