[2개의 그룹을 병합하는 과정]
시간 제한 2초, 실버 V, 백준 2751번
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.
5 # 수의 개수 5 4 3 2 1
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
1 2 3 4 5
# 병합 정렬 구현
병합 정렬(s, e):
s(시작점), e(종료점), m(중간점)
# 재귀 함수 형태로 구현
병합 정렬(s, m)
병합 정렬(m+1, e)
for s~e:
tmp 리스트 저장
# 두 그룹을 병합하는 로직
index1 -> 앞쪽 그룹 시작점
index2 -> 뒤쪽 그룹 시작점
while index1 <= 중간점 and index2 <= 종료점:
양쪽 그룹의 index가 가리키는 값을 비교한 후 더 작은 수를 선택해 리스트에 저장하고
선택된 데이터의 index값을 오른쪽으로 한 칸 이동
반복문이 끝난 후 남아 있는 데이터 정리
N(정렬할 수 개수)
A(정렬할 리스트 선언)
tmp(정렬할 때 잠시 사용할 임시 리스트 선언)
for(N의 개수만큼):
A 리스트에 데이터 저장하기
병합 정렬 함수 수행
결괏값 출력
import sys
input = sys.stdin.readline
print = sys.stdout.write
def merge_sort(s, e): # 병합 정렬 수행
if e - s < 1: return
m = int(s + (e - s) / 2)
merge_sort(s, m)
merge_sort(m + 1, e)
for i in range(s, e + 1):
tmp[i] = A[i]
k = s
index1 = s
index2 = m + 1
while index1 <= m and index2 <= e: # 두 그룹을 병합하는 로직
if tmp[index1] > tmp[index2]:
A[k] = tmp[index2]
k += 1
index2 += 1
else:
A[k] = tmp[index1]
k += 1
index1 += 1
while index1 <= m: # 한쪽 그룹이 모두 선택된 후 남아 있는 값 정리
A[k] = tmp[index1]
k += 1
index1 += 1
while index2 <= e:
A[k] = tmp[index2]
k += 1
index2 += 1
N = int(input())
A = [0] * int(N+1)
tmp = [0] * int(N+1)
for i in range(1, N+1):
A[i] = int(input())
merge_sort(1, N)
for i in range(1, N+1):
print(str(A[i]) + '\n')
시간 제한 1초, 플래티넘, 백준 1517번
N개의 수로 이루어진 수열 A[1], A[2], …, A[N]이 있다. 이 수열에 대해서 버블 소트를 수행할 때, Swap이 총 몇 번 발생하는지 알아내는 프로그램을 작성하시오.
버블 소트는 서로 인접해 있는 두 수를 바꿔가며 정렬하는 방법이다. 예를 들어 수열이 3 2 1 이었다고 하자. 이 경우에는 인접해 있는 3, 2가 바뀌어야 하므로 2 3 1 이 된다. 다음으로는 3, 1이 바뀌어야 하므로 2 1 3 이 된다. 다음에는 2, 1이 바뀌어야 하므로 1 2 3 이 된다. 그러면 더 이상 바꿔야 할 경우가 없으므로 정렬이 완료된다.
첫째 줄에 N(1 ≤ N ≤ 500,000)이 주어진다. 다음 줄에는 N개의 정수로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0 ≤ |A[i]| ≤ 1,000,000,000의 범위에 들어있다.
3 # 수의 개수 3 2 1
첫째 줄에 Swap 횟수를 출력한다.
3
# 병합 정렬 구현
병합 정렬(s, e):
s(시작점), e(종료점), m(중간점)
# 재귀 함수 형태로 구현
병합 정렬(s, m)
병합 정렬(m+1, e)
for s~e:
tmp 리스트 저장
# 두 그룹을 병합하는 로직
index1 -> 앞쪽 그룹 시작점
index2 -> 뒤쪽 그룹 시작점
while index1 <= 중간점 and index2 <= 종료점:
양쪽 그룹의 index가 가리키는 값을 비교한 후 더 작은 수를 선택해 리스트에 저장하고
선택된 데이터의 index값을 오른쪽으로 한 칸 이동
반복문이 끝난 후 남아 있는 데이터 정리
로직을 수행하면서 뒤쪽 데이터 값이 더 작아 선택될 때
swap이 일어난 것과 동일한 것이기 때문에
현재 남은 앞쪽 그룹 데이터의 개수만큼 결괏값에 더해 줌
N(정렬할 수 개수)
A(정렬할 리스트 선언)
tmp(정렬할 때 잠시 사용할 임시 리스트 선언)
A 리스트에 데이터 저장하기
병합 정렬 함수 수행
결괏값 출력
import sys
input = sys.stdin.readline
result = 0
def merge_sort(s, e): # 병합 정렬 수행
global result
if e - s < 1: return
m = int(s + (e - s) / 2)
merge_sort(s, m) # 재귀 함수의 형태로 구현
merge_sort(m + 1, e)
for i in range(s, e + 1):
tmp[i] = A[i]
k = s
index1 = s
index2 = m + 1
while index1 <= m and index2 <= e: # 두 그룹을 병합하는 로직
if tmp[index1] > tmp[index2]:
A[k] = tmp[index2]
result = result + index2 - k # 뒤쪽 데이터 값이 더 작다면 결괏값 업데이트
k += 1
index2 += 1
else:
A[k] = tmp[index1]
k += 1
index1 += 1
while index1 <= m: # 한쪽 그룹이 모두 선택된 후 남아 있는 값 정리
A[k] = tmp[index1]
k += 1
index1 += 1
while index2 <= e:
A[k] = tmp[index2]
k += 1
index2 += 1
N = int(input())
A = list(map(int, input().split()))
A.insert(0, 0)
tmp = [0] * int(N+1)
merge_sort(1, N)
print(result)
[기수 정렬의 핵심 이론]
시간 제한 3초, 실버 V, 백준 10989번
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.
10 5 2 3 1 4 2 3 5 1 7
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
1 1 2 2 3 3 4 5 5 7
N(정렬할 수 개수)
count(카운팅 정렬 리스트)
for N만큼 반복:
count 리스트에 현재 수에 해당하는 index의 값 1 증가
for i는 0~10000까지:
만약 count[i]의 값이 0이 아니면 # i가 기존 input에 있는 수
해당 값만큼 i를 반복하여 출력
import sys
input = sys.stdin.readline
N = int(input())
count = [0] * 10001
for i in range(N):
count[int(input())] += 1
for i in range(10001):
if count[i] != 0:
for _ in range(count[i]): # 해당 index값 만큼 index를 반복하여 출력
print(i)