- 기준점(pivot)을 정해서 기준점보다 작은 데이터는 왼쪽(left), 큰 데이터는 오른쪽(right)으로 모으는 함수를 작성.
- 각 왼쪽(left), 오른쪽(right)은 재귀용법을 사용해서 다시 동일 함수를 호출하여 위 작업을 반복.
- 함수는 왼쪽(left) + 기준점(pivot) + 오른쪽(right) 을 리턴함.
=================================
index : 0 1 2 3 4 5 6 7
value : 49 97 53 5 33 65 62 51
=================================
pivot선택 : (index : 0, value : 49)
p1 (1회)
pivot - (index : 0, value : 49)
[left] - (index : 3, value : 5), (index : 4, value : 33)
[right] -(index : 1, value : 97), (index : 2, value : 53), (index : 5, value : 65), (index : 6, value : 62), (index : 7, value : 51)
p2(2회)
p1의 [left]
pivot - (index : 3, value : 5)
[left] -
[right] -(index : 4, value : 33)
p1의 [right]
pivot - (index : 1, value : 97)
[left] - (index : 2, value : 53), (index : 5, value : 65), (index : 6, value : 62), (index : 7, value : 51)
[right] -
. . . (이런식으로 데이터 수가 1개가 될 때까지...재귀함수 => 분할)
분할과정이 끝나면 합치기(정복)
...(앞부분 과정은 생략)
[left] - (index : 3, value : 5), (index : 4, value : 33)
[pivot] - (index : 0, value : 49)
[right] - (index : 7, value : 51), (index : 2, value : 53), (index : 6, value : 62), (index : 5, value : 65), (index : 1, value : 97)
[merge] - (index : 3, value : 5), (index : 4, value : 33) + (index : 0, value : 49) + (index : 7, value : 51), (index : 2, value : 53), (index : 6, value : 62), (index : 5, value : 65), (index : 1, value : 97)
[원리 시각화]
https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/visualize/
Quick Sort visualize | Sorting | Algorithms | HackerEarth
Visualize your learning on Quick Sort to improve your understanding of Algorithms.
www.hackerearth.com
#코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import sys
def quickSort(arr, start, end):
if start >= end:
return
else:
pivot = start
left = start + 1
right = end
while left <= right:
# pivot보다 큰 데이터를 찾을 때까지 반복
while left <= end and arr[left] <= arr[pivot]: # 처음 경우 : arr[left] = 7, arr[pivot] = 5 이므로 while문을 타지 않는다.
left += 1
# pivot보다 작은 데이터를 찾을 때까지 반복
while right > start and arr[right] >= arr[pivot]: # 처음 경우 : arr[right] = 8, arr[pivot] = 5 이므로 while문을 돈다.
right -= 1
if left > right: # 위치가 엇갈렸다면 작은 데이터와 피벗의 위치를 교체
arr[right], arr[pivot] = arr[pivot], arr[right]
else: # 위치가 엇갈리지 않았다면 작은 데이터와 큰 데이터의 위치를 교체
arr[left], arr[right] = arr[right], arr[left]
# 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행
quickSort(arr, start, right-1)
quickSort(arr, right+1, end)
if __name__ == "__main__":
input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
quickSort(arr, 0, n-1)
print(*arr)
|
cs |
#입력
10
5 7 9 0 3 1 6 2 4 8
#코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import sys
def quickSort(arr):
if len(arr) <= 1:
return arr
else:
pivot = arr[0] # pivot은 첫 번째 원소
tail = arr[1:] # pivot을 제외한 리스트
left_side = [x for x in tail if x <= pivot] # 분할된 왼쪽부분
right_side = [x for x in tail if x > pivot] # 분할된 오른쪽부분
return quickSort(left_side) + [pivot] + quickSort(right_side)
if __name__ == "__main__":
input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
print(*quickSort(arr))
|
cs |
#코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import random
def qsort(data):
if len(data) <= 1:
return data
left, right = list(), list()
pivot = data[0]
for i in range(1, len(data)):
if pivot > data[i]: #왼쪽
left.append(data[i])
else: #오른쪽
right.append(data[i])
return qsort(left) + [pivot] + qsort(right)
data_list = random.sample(range(100), 10)
print(data_list)
data_list = qsort(data_list)
print(data_list)
|
cs |
*시간복잡도 : O(nlogn)
*최악 : O(n^2)
// 자바 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
import java.util.*;
import java.io.*;
public class Main{
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int n;
static int[] arr;
public static void main(String[] args) throws Exception {
// Please Enter Your Code Here
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
arr = new int[n];
for(int i=0; i<n; i++) arr[i] = Integer.parseInt(st.nextToken());
quickSort(0, n-1);
StringBuilder sb = new StringBuilder();
for(int i=0; i<n; i++) {
sb.append(String.valueOf(arr[i]) + " ");
}
bw.write(String.valueOf(sb));
br.close();
bw.flush();
bw.close();
}
// arr을 start부터 end까지 퀵정렬 하는 함수.
static void quickSort(int start, int end) {
if(start>=end) return;
int pivot = arr[start];
int[] left = new int[n];
int[] right = new int[n];
int leftCnt = getLeft(start+1, end, pivot, left);
int rightCnt = getRight(start+1, end, pivot, right);
for(int i=0; i<leftCnt; i++) {
arr[start+i] = left[i];
}
arr[start+leftCnt] = pivot;
for(int i=0; i<rightCnt; i++) {
arr[start+leftCnt+1+i] = right[i];
}
quickSort(start, start+leftCnt-1); // -1은 pivot을 뺀값.
quickSort(start+leftCnt+1, end);
}
// arr의 start부터 end까지 숫자들 중에서
// pivot 보다 작거나 같은 값을 result에 채우는 함수.
// 또한, 작거나 같은 원소의 개수를 반환한다.
static int getLeft(int start, int end, int pivot, int[] result){
int idx=0;
for(int i=start; i<=end; i++) {
if(arr[i]<=pivot) {
result[idx++] = arr[i];
}
}
return idx;
}
// arr의 start부터 end까지 숫자들 중에서
// pivot 보다 큰 값을 result에 채우는 함수.
// 또한, 큰 원소의 개수를 반환한다.
static int getRight(int start, int end, int pivot, int[] result){
int idx=0;
for(int i=start; i<=end; i++) {
if(arr[i]>pivot) {
result[idx++] = arr[i];
}
}
return idx;
}
}
|
cs |
'CS > 알고리즘_개념' 카테고리의 다른 글
이진탐색(Binary Search), 순차탐색(Sequential Search) + Parametric Search (0) | 2021.05.19 |
---|---|
병합정렬(merge sort) (0) | 2021.05.18 |
동적계획법과 분할정복 : Dynamic Programing & Divide and Conquer (0) | 2021.05.18 |
재귀용법2(recursive call, 재귀호출) : Brute-Force Algorithm (0) | 2021.05.18 |
재귀용법(recursive call, 재귀호출) (0) | 2021.05.18 |