- 호어 파티션 방식
import java.util.Arrays;
public class 퀵정렬_호어파티션 {
static int[] arr;
static boolean[] flag;
public static void main(String[] args) {
arr = new int[] {3, 1, 4, 6, 9, 2, 8, 7, 5};
flag = new boolean[arr.length];
hoare(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void hoare(int[]arr, int left, int right) {
//피봇 정하기(이 경우 제일 왼쪽값으로 정한 것.)
int pivot = arr[left];
//왼쪽 포인터 인덱스 지정 : pivot보다 큰 값을 찾아가는 포인터
int l = left +1;
//오른쪽 포인터 인덱스 지정 : pivot보다 작은 값을 찾아가는 포인터
int r = right;
int finish = 0;
//왼쪽과 오른쪽이 교차되지 않은 동안만 동작
while(l<=r) {
//왼쪽포인터는 pivot보다 작으면 지나침
while(l<=r && arr[l]<=pivot) {
l++;
}
//오른쪽 포인터는 pivot보다 크면 지나침
while(l<=r && arr[r]>pivot) {
r--;
}
//위 while문을 다 돌고도 l<r이면 l과 r의 arr원소 바꾸고 또 while문 반복
if(l<r) swap(l, r);
}
//위 while문이 끝났다는건 l과 r이 교차됐다는 뜻이자,
//배열이 pivot보다 (작거나 같은 값들)(큰값들)의 묶음으로 정렬되었다는 뜻.
//pivot은 맨 앞에 있으므로 자기보다 작은애랑 자리를 바꿔야 위의 묶음 정렬을 해치지 않으며
//pivot보다 작은 값을 찾던 pointer는 r이므로 r과 swap
swap(left, r);
//r이 left+1보다 크거나 같다는 건 왼쪽에 더 정렬할 원소가 2개 이상 남았다는 뜻이므로 정렬
if(r>=left+1) hoare(arr,left,r-1);
//오른쪽에 정렬할 원소가 남았는지 체크하고 정렬
if(r<=right-2) hoare(arr,r+1, right);
}
public static void swap(int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
- 로무토 파티션 방식1
package Silver5;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main_24090퀵2 {
static int N;
static int K;
static int[] arr;
static int cnt;
static boolean flag;
static String answer;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
cnt = 0;
arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
sort(0, N - 1);
if (!flag) {
System.out.println(-1);
}else {
System.out.println(answer);
}
}
public static void sort(int left, int right) {
if(left<right) {
int q = partition(left, right);
sort(left, q-1);
sort(q+1, right);
}
}
public static int partition(int left, int right) {
int pivot = arr[right];
int i = left - 1; // pivot보다 작거나 같은 원소들의 끝지점을 가리킬 포인터
for (int j = left; j < right; j++) {
if (arr[j] <= pivot) {
i++;
swap(i, j);
}
}
if (i + 1 != right) {
swap(i+1, right);
}
return i + 1;
}
public static void swap(int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
cnt++;
if (cnt == K) {
if (arr[i] <= arr[j]) {
answer = String.valueOf(arr[i]) + " " + String.valueOf(arr[j]);
} else {
answer = String.valueOf(arr[j]) + " " + String.valueOf(arr[i]);
}
flag = true;
}
}
}
- 로무토파티션 방식2
import java.util.Arrays;
public class 퀵정렬_로무토파티션 {
static int[] arr;
static boolean[] flag;
public static void main(String[] args) {
//언제? //
arr = new int[] {3, 1, 4, 6, 9, 2, 8, 7, 5};
flag = new boolean[arr.length];
lomuto(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void lomuto(int[] arr, int left, int right) {
int pivot = arr[right];
int i = left -1;
int finish =0;
for(int j=left; j<right; j++) {
if(arr[j]<=pivot) {
i ++;
swap(i, j);
}
}
swap(i+1, right);
flag[i+1] = true;
for(int k=0; k<flag.length; k++) {
if(flag[k]) finish++;
}
if(finish == flag.length) return;
finish = 0;
if(i>left) lomuto(arr, left, i);
if(i+1<=right-2) lomuto(arr, i+2, right);
}
public static void swap(int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
'Learning-log -CS > Data Structure & Algorithm' 카테고리의 다른 글
(자료구조 & 알고리즘 정리) 재귀, 완전탐색, 순열, 조합, 부분집합 정리(2023.06.04) (0) | 2023.06.05 |
---|---|
알고리즘 - 이분탐색(Binary Search)과 매개변수 탐색(Parameter Search) (Java, Python) (0) | 2023.04.20 |
알고리즘 - 병합정렬 (0) | 2023.03.27 |
알고리즘 - 백트래킹&순열 (0) | 2023.03.27 |
알고리즘 - 조합 (0) | 2023.03.26 |