# 문제 설명
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.
출력
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
# 정답 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(st.nextToken()); //수의 개수
int[] arr = new int[N];
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
arr[n] = Integer.parseInt(st.nextToken());
}
for (int end = N-1; end > 0; end--) { //4 3 2 1
for (int start = 0; start < end; start++) {
if (arr[start+1] < arr[start]) {
swap(arr, start, start+1);
}
}
}
for (int a : arr) {
sb.append(a + "\n");
}
System.out.print(sb);
}
public static void swap(int[] arr, int a, int b) {
int num = arr[a];
arr[a] = arr[b];
arr[b] = num;
}
}
버블 정렬을 이용하였다.
end를 4, 3, 2, 1로 지정하여 루프 범위를 설정했다.
end가 4일 때는 루프 범위가 0~4, end가 3일 때는 루프 범위가 0~3이 된다.
start는 0부터 시작하여 end-1까지 1씩 증가한다.
0번째 값과 1번째 값을 비교하고, 1번째 값과 2번째 값을 비교하는 순서이다.
오름차순으로 수를 정렬해야하므로, 만약 start+1번째 값이 start번째 값보다 작으면 swap해준다.
# 다른 풀이 1
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(st.nextToken()); //수의 개수
int[] A = new int[N];
int max = 0;
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
A[n] = Integer.parseInt(st.nextToken());
if (max < Math.abs(A[n])) {
max = Math.abs(A[n]);
}
}
int maxLength = 0;
while (max != 0) {
max /= 10;
maxLength++;
}
radixSort(A, maxLength);
for (int n : A) {
sb.append(n + "\n");
}
System.out.print(sb);
}
public static void radixSort(int[] arr, int maxLength) {
Queue<Integer>[] positiveBucket = new LinkedList[10]; //0~9
Queue<Integer>[] negativeBucket = new LinkedList[10]; //음수용 버킷
for (int i = 0; i < positiveBucket.length; i++) {
positiveBucket[i] = new LinkedList<>();
negativeBucket[i] = new LinkedList<>();
}
int m = 1; //자릿수
while (maxLength != 0) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= 0) {
positiveBucket[(arr[i] / m) % 10].add(arr[i]);
}
else {
negativeBucket[(Math.abs(arr[i]) / m) % 10].add(arr[i]);
}
}
int j = 0;
for (int i = negativeBucket.length-1; i >= 0; i--) {
while (!negativeBucket[i].isEmpty()) {
arr[j++] = negativeBucket[i].poll();
}
}
for (int i = 0; i < positiveBucket.length; i++) {
while (!positiveBucket[i].isEmpty()) {
arr[j++] = positiveBucket[i].poll();
}
}
m *= 10;
maxLength--;
}
}
}
기수 정렬을 이용하였다.
입력 받은 수의 최대 자릿수를 구해 maxLength에 저장한다.
radixSort 함수에 정렬할 배열, 최대 자릿수를 입력한다.
입력 받은 수는 절댓값이 1000보다 작거나 같은 정수로 음수일 수도 있다.
기수 정렬에서는 값의 자릿수만 보고 비교하므로 음수, 양수를 비교할 수 없다.
따라서 음수를 저장할 버킷과 양수를 저장할 버킷을 각각 만든다.
자릿수는 1부터 최대 자릿수까지 증가한다.
양수와 음수를 나눠 각 자릿수에 맞는 큐에 값을 넣는다.
그 다음 큐에 있는 값들을 빼 오름차순 정렬이 되도록 기존 배열에 저장한다.
양수 버킷은 큐를 0부터 9까지 돌며 poll하면 된다.
그러나 음수는 숫자가 클수록 더 작으므로 양수와 반대로 큐를 9부터 0까지 돌며 poll한다.
# 다른 풀이 2
import java.io.*;
import java.util.*;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); //수의 개수
int[] A = new int[N];
int max = 0;
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
A[n] = Integer.parseInt(st.nextToken());
if (max < Math.abs(A[n])) {
max = Math.abs(A[n]);
}
}
countingSort(A, max);
System.out.print(sb);
}
public static void countingSort(int[] A, int max) {
int[] arr = A;
int[] positiveCnt = new int[max+1]; //양수
int[] negativeCnt = new int[max+1]; //음수
for (int a : arr) {
if (a >= 0) {
positiveCnt[a]++;
}
else {
negativeCnt[Math.abs(a)]++;
}
}
for (int i = negativeCnt.length-1; i > 0; i--) {
for (int j = 0; j < negativeCnt[i]; j++) {
sb.append("-" + i + "\n");
}
}
for (int i = 0; i < positiveCnt.length; i++) {
for (int j = 0; j < positiveCnt[i]; j++) {
sb.append(i + "\n");
}
}
}
}
계수 정렬을 이용하여 풀었다.
입력 받은 수의 절댓값 중 최댓값을 구한다.
countingSort 함수에 정렬할 배열과 최댓값을 저장한다.
입력 받은 수는 음수일 수 있으므로, 수를 셀 배열을 최댓값 크기로 양수, 음수 각각 만들어준다.
arr 배열의 데이터를 순회하며 각 수가 나온 횟수를 positiveCnt와 negativeCnt에 센다.
오름차순 정렬로 출력해야 하므로 음수 배열 먼저 출력해준다.
그 후 양수 배열을 출력해준다.
'백준' 카테고리의 다른 글
[1377] 버블 소트 (JAVA) (0) | 2024.03.23 |
---|---|
[23968] 알고리즘 수업 - 버블 정렬 1 (JAVA) (1) | 2024.03.22 |
[17298] 오큰수 (JAVA) (1) | 2024.03.21 |
[11286] 절댓값 힙 (0) | 2024.03.21 |
[2164] 카드2 (JAVA) (0) | 2024.03.21 |