- Soting Algorithm Properties
- Complexity
- In-place
- Stable
- Parallel
-
Bubble Sort :
$O(n^{2})$ -
Insertion Sort :
$O(n^{2})$ -
Selection Sort :
$O(n^{2})$ -
Merge Sort :
$O(n \log n)$ -
Quick Sort : ํ๊ท :
$O(n \log n)$ , ์ต์ :$O(n^2)$ -
Shell Sort :
$O(n^{2})$ ~$O(n \log n)$ ~$O(n \log ^{2} n)$ -
Heap Sort :
$O(n \log n)$ -
Counting Sort :
$O(n)$ -
Radix Sort :
$O(cn)$ - Parallel Sorting Algorithm
-
Bitonic Sort :
$O( \log ^{2} n)$ parallel time -
Odd-even transposition Sort :
$O(n)$ parallel time -
Odd-even merge Sort :
$O( \log ^{2} n)$ parallel time
๋ฐฑ๋ฌธ์ด ๋ถ์ฌ์ผ๊ฒฌ.
๋์์ด ๋๋ ์ฌ์ดํธ : visualgo.net
Algorithm | Time | Stable | In-place | Notes |
---|---|---|---|---|
Bubble Sort | Yes | Yes | - Slow (good for small inputs) - Easy to implement |
|
Insertion Sort | Yes | Yes | - Slow (good for small inputs) - Easy to implement |
|
Selection Sort | No | Yes | - Slow (good for small inputs) - Easy to implement - Un-stable algorithm |
|
Merge Sort | Yes | No | - Fast (good for huge inputs) - Sequential data access - Not in-place algorithm |
|
Quick Sort | No or Yes | Yes or No | - Fastest (good for large inputs) - In-place, randomized |
Bubble Sort๋ "Exchange Sort" ๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค.
void exchangesort (int n, keytype S[]) {
index i, j;
for (i = 1; i <= n-1; i++)
for (j = i+1; j <= n; j++)
if (S[j] < S[i])
exchange S[i] and S[j];
}
- ๋ด๋ฆผ์ฐจ์์ ์ค๋ฆ์ฐจ์์ผ๋ก ๋ฐ๊พธ๋ ค๋ฉด 5๋ฒ ์ค์
if (S[j] < S[i])
์ ๋ถ๋ฑํธ ๋ฐฉํฅ์ ๋ฐ๋๋ก ๋ฐ๊พธ๋ฉด ๋๋ค. - 5๋ฒ ์ค์
if (S[j] < S[i])
์์S[j]
์S[i]
๋$n^{2}$ ๋ฒ ๋น๊ต๋๋ค. - 6๋ฒ ์ค์
exchange
์ฐ์ฐ์ ์๋์ 3๋จ๊ณ ์ฐ์ฐ์ ๊ฑฐ์น๋ค.
temp = a;
a = b;
b = temp;
๊ทธ๋ฌ๋ฏ๋ก Time Complexity๋
void insertionsort(int n, keytype S[])
{
index i, j;
keytype x;
for (i = 2; i < n; i++) {
x = S[i];
j = i - 1;
while (j > 0 && S[j] > x) {
S[j+1] = S[j];
j--;
}
S[j+1] = x;
}
}
- 6๋ฒ ์ค์
for (i = 2; i < n; i++)
์์i
๊ฐ 2๋ถํฐ ์์ํ๋ ์ด์ ๋i
๊ฐ 1์ผ ๋๊ฐ ์ด๊ธฐ๊ฐ์ด๊ธฐ ๋๋ฌธ์ด๋ค.- ํ๋๋ง ๋น๊ตํ์ ๋๋ ๊ทธ ํ๋๊ฐ ๋น์ฐํ ์ ๋ ฌ๋ ์ํ์
- 9๋ฒ ์ค์
while (j > 0 && S[j] > x)
์์S[j]
๊ณผx
๋$n^{2}$ ๋ฒ ๋น๊ต๋๋ค. - ๋ง์ฐฌ๊ฐ์ง๋ก, 10๋ฒ ์ค (
S[j+1] = S[j];
)์$n^{2}$ ๋ฒ ํ ๋น๋๋ค.
์ฃผ์ด์ง i
์ ๋ํด i-1
๋ฒ์ ๋น๊ต๊ฐ ์ด๋ฃจ์ด์ง๋ค.
๊ทธ๋ฌ๋ฏ๋ก Time Complexity๋
์ฃผ์ด์ง i
์ ๋ํด, x
๊ฐ ์ฝ์
๋ ์ ์๋ ์ฅ์๋ i
๊ณณ์ด ์๋ค.
๋ฐ๋ผ์ ํ๊ท ๋น๊ต ํ์๋
void selectionsort(int n, keytype S[])
{
index i, j, smallest;
for (i = 0; i < n-1; i++) {
smallest = i;
for (j = i+1; j <= n; j++)
if (S[j] < S[smallest])
smallest = j;
exchange S[i] and S[smallest];
}
}
- 7๋ฒ ์ค์
for (j = i+1; j <= n; j++)
์์j
์n
์$n^{2}$ ๋ฒ ๋น๊ต๋๋ค. - 10๋ฒ ์ค์
exchange S[i] and S[smallest];
์์๋ ํ ๋น์ด$3n$ ๋ฒ ์ด๋ฃจ์ด์ง๋ค.
์๊ณ ๋ฆฌ์ฆ | ๋น๊ตํ์ | ์ง์ ํ์ | ์ถ๊ฐ์ ์ฅ์ ์ฌ์ฉ๋ |
---|---|---|---|
Bubble Sort |
|
์ ์๋ฆฌ์ ๋ ฌ | |
Insertion Sort |
|
|
์ ์๋ฆฌ์ ๋ ฌ |
Selection Sort | ์ ์๋ฆฌ์ ๋ ฌ |
- ์ฝ์ ์ ๋ ฌ์ ๋ฒ๋ธ์ ๋ ฌ ๋ณด๋ค๋ ํญ์ ์ต์ํ ๋น ๋ฅด๊ฒ ์ํ๋๋ค๊ณ ํ ์ ์๋ค.
- ์ ํ์ ๋ ฌ์ด ๋ฒ๋ธ์ ๋ ฌ ๋ณด๋ค ๋น ๋ฅธ๊ฐ?
- ์ผ๋ฐ์ ์ผ๋ก๋ ์ ํ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ๋น ๋ฅด๋ค๊ณ ํ ์ ์๋ค.
- ๊ทธ๋ฌ๋ ์ ๋ ฅ์ด ์ด๋ฏธ ์ ๋ ฌ๋์ด ์๋ ๊ฒฝ์ฐ, ์ ํ์ ๋ ฌ์ ์ง์ ์ด ์ด๋ฃจ์ด์ง์ง๋ง ๋ฒ๋ธ์ ๋ ฌ์ ์ง์ ์ด ์ด๋ฃจ์ด์ง์ง ์์ผ๋ฏ๋ก ๋ฒ๋ธ์ ๋ ฌ์ด ๋น ๋ฅด๋ค.
- ์ ํ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ์ฝ์
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ๋ณด๋ค ๋น ๋ฅธ๊ฐ?
-
$n$ ์ ํฌ๊ธฐ๊ฐ ํฌ๊ณ ,ํค์ ํฌ๊ธฐ๊ฐ ํฐ ์๋ฃ๊ตฌ์กฐ ์ผ ๋๋ ์ง์ ํ๋ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ฏ๋ก ์ ํ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ๋ ๋น ๋ฅด๋ค.
-
void mergesort (int n, keytype S[]) {
const int h = n / 2, m = n - h;
keytype U[1..h], V[1..m];
if (n > 1) {
copy S[1] through S[h] to U[1] through U[h];
copy S[h+1] through S[n] to V[1] through V[m];
mergesort(h,U);
mergesort(m,V);
merge(h,m,U,V,S);
}
}
void merge (int h, int m, const keytype U[], const keytype V[], const keytype S[])
{
index i, j, k;
i = 1; j = 1; k = 1;
while (i <= h && j <= m) {
if (U[i] < V[j]) {
S[k] = U[i];
i++;
} else {
S[k] = V[j];
j++;
}
k++;
}
if (i > h)
copy V[j] through V[m] to S[k] through S[h+m];
else
copy U[i] through U[h] to S[k] through S[h+m];
}
- Analysis of Merge-Sort
- The height
h
of the merge-sort tree is$O(log n)$ - at each recursive call we divide in half the sequence,
- The overall amount or work done at the nodes of depth
i
is$O(n)$ - we partition and merge
$2^i$ sequences of size$n/2^i$ - we make
$2^(i+1)$ recursive calls
- we partition and merge
- Thus, the total running time of merge-sort is
$O(n \log n)$
- The height
- in-place sort ์๊ณ ๋ฆฌ์ฆ (์ ์๋ฆฌ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ)
- ์ ๋ ฅ์ ์ ์ฅํ๋๋ฐ ํ์ํ ๋งํผ ์ ์ฅ์ฅ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ
- mergesort ์๊ณ ๋ฆฌ์ฆ์ in-place sort ์๊ณ ๋ฆฌ์ฆ์ด ์๋๋ค.
- ์๋ํ๋ฉด ์ ๋ ฅ์ธ ๋ฐฐ์ด S ์ด์ธ์ U์ V๋ฅผ ์ถ๊ฐ๋ก ๋ง๋ค์ด์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
- ๊ทธ๋ฌ๋ฉด ์ผ๋ง๋งํผ์ ์ถ๊ฐ์ ์ธ ์ ์ฅ์ฅ์๊ฐ ํ์ํ ๊น?
- mergesort๋ฅผ ์ฌ๊ทํธ์ถํ ๋๋ง๋ค ํฌ๊ธฐ๊ฐ S์ ๋ฐ์ด ๋๋ U์ V๊ฐ ์ถ๊ฐ์ ์ผ๋ก ํ์ํ๋ค.
- merge ์๊ณ ๋ฆฌ์ฆ์์๋ U์ V๊ฐ ์ฃผ์๋ก ์ ๋ฌ์ด ๋์ด ๊ทธ๋ฅ ์ฌ์ฉ๋๋ฏ๋ก ์ถ๊ฐ์ ์ธ ์ ์ฅ์ฅ์๋ฅผ ๋ง๋ค์ง ์๋๋ค.
๋ฐ๋ผ์ mergesort๋ฅผ ์ฌ๊ทํธ์ถํ ๋๋ง๋ค ์ผ๋ง๋งํผ์ ์ถ๊ฐ์ ์ธ ์ ์ฅ์ฅ์๊ฐ ๋ง๋ค์ด์ ธ์ผ ํ๋์ง๋ฅผ ๊ณ์ฐํด ๋ณด๋ฉด ๋๋ค. - ์ฒ์ S์ ํฌ๊ธฐ๊ฐ n์ด๋ฉด ์ถ๊ฐ์ ์ผ๋ก ํ์ํ U์ V์ ์ ์ฅ์ฅ์ ํฌ๊ธฐ์ ํฉ์ n์ด ๋๋ค. ๋ค์ ์ฌ๊ทํธ์ถ์๋ n์ ์ถ๊ฐ
์ ์ผ๋ก ํ์ํ ์ด ์ ์ฅ์ฅ์์ ํฌ๊ธฐ๋
$n + \frac{n}{2} + \frac{n}{4} + \cdots = 2n$ ์ด๋ค.
- ๊ฒฐ๋ก ์ ์ผ๋ก ์ด ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๊ฐ๋ณต์ก๋๋
$2n\in \Theta (n)$ ์ด๋ผ๊ณ ํ ์ ์๋ค. - ์ถ๊ฐ์ ์ผ๋ก ํ์ํ ์ ์ฅ์ฅ์๊ฐ n์ด ๋๋๋ก, ์ฆ, ๊ณต๊ฐ๋ณต์ก๋๊ฐ n์ด ๋๋๋ก ์๊ณ ๋ฆฌ์ฆ์ ํฅ์์ํฌ ์ ์๋ค (HOW?).
- ๊ทธ๋ฌ๋ ํฉ๋ณ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ์ ์๋ฆฌ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ๋ ์๋ ์๋ค.
- ๋น ๋ฅธ ์ ๋ ฌ(Quicksort)์ด๋ ์ด๋ฆ์ด ์คํด์ ์ฌ์ง๊ฐ ์๋ค. ์๋ํ๋ฉด ์ฌ์ค ์ ๋์ ์ผ๋ก ๊ฐ์ฅ ๋น ๋ฅธ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด๋ผ๊ณ ํ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฐจ๋ผ๋ฆฌ โ๋ถํ ๊ตํ์ ๋ ฌ(partition exchange sort)โ๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฒ ๋ ์ ํํ๋ค.
- Quick-sort๋ divide-and-conquer paradigm์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ randomized sorting algorithm์ด๋ค.
- Divide: pick a random element x (called pivot) and partition S into
- L elements less than x
- E elements equal x
- G elements greater than x
- Recur: sort L and G
- Conquer: join L, E and G
- Divide: pick a random element x (called pivot) and partition S into
Algorithm inPlaceQuickSort(S, a, b)
if a >= b then return
p = S.elemAtRank(b) // pivotting
l = a
r = b-1
while (l <= r) // partioning
{
while (l <= r and S.elemAtRank(l) <= p)
l++;
while (l <= r and S.elemAtRank(r) >= p)
r--;
if (l < r)
S.swap(S.atRank(l), S.atRank(r));
}
S.swap(S.atRank(l), S.atRank(b));
inPlaceQuickSort(S, a, l-1)
inPlaceQuickSort(S, l+1, b)
- The worst case for quick-sort occurs when the pivot is the unique minimum or maximum element
- One of
L
andG
has sizen - 1
and the other has size 0 - The running time is proportional to the sum
n + (n - 1) + ... + 2 + 1
- Thus, the worst-case running time of quick-sort is
O(n^2)
- Best-case is
O(n log n)
- Best-case is
- The expected height of the quick-sort tree is
O(log n)
- The amount or work done at the nodes of the same depth is
$O(n)$ - Thus, the expected running time of quick-sort is
O(n log n)
- ์คํ์ ์ฌ์ฉํ์ฌ ์ํ์ ์ ๊ฑฐ
- ์์ ๋ถ๋ถํ์ผ์ ๊ฒฝ์ฐ ์ฝ์ ์ ๋ ฌ ์ฌ์ฉ
- ์ค๊ฐ๊ฐ ๋ถํ (Median-of-Three Partioning)
void QuickSort(int a[], int l, int r)
{
int i, j, v;
for (;;) {
while (r > l) {
i = partition(a, l, r);
if (i-l > r-i) {
push(&top, l); push(&top, i-1); l = i+1;
} else {
push(&top, i+1); push(&top, r); r = i-1;
}
}
if (top < 0) break;
r = pop(&top);
l = pop(&top);
}
}
if (r>l)
์if (r-l <= M) { InsertionSort(a, l, r) }
๋ก- M ๊ฐ์ผ๋ก 5 ~ 25 ์ฌ์ฉ
void QuickSort(int a[], int l, int r)
{
int i, j, v;
if (r-l <= M) // ํํฐ์
์ ํฌ๊ธฐ๊ฐ M๋ณด๋ค ์์ผ๋ฉด
InsertionSort(a, l, r); // ๊ทธ๋ฅ n^2์ ์ฐ์
else {
// ์ฌ๊ธฐ์๋ถํฐ
v = a[r]; i = l-1; j = r;
for ( ; ; ) {
while (a[++i] < v);
while (a[--j] > v);
if (i >= j) break;
swap(a, i, j);
}
swap(a, i, r);
// ์ฌ๊ธฐ๊น์ง๋ ๋์ผํ๋ค.
QuickSort(a, l, i-1);
QuickSort(a, i+1, r);
}
}
- ๋ง์ ์์ฉ์์ ์ฝ 20% ์ ๋์ ์๊ฐ ์ ๊ฐ ํจ๊ณผ๊ฐ ์์
- ๋ถํ ์์๋ฅผ ์ ํํ ๋ ์ผ์ชฝ, ๊ฐ์ด๋ฐ, ์ค๋ฅธ์ชฝ ์์ ์ค ๊ฐ์ด ์ค๊ฐ์ธ ์์๋ฅผ ์ ํ
- ์ผ์ชฝ, ๊ฐ์ด๋ฐ, ์ค๋ฅธ์ชฝ ์์๋ฅผ ์ ๋ ฌํ ํ ๊ฐ์ฅ ์์ ๊ฐ์
a[l]
, ๊ฐ์ฅ ํฐ ๊ฐ์a[r]
, ์ค๊ฐ ๊ฐ์a[r-1]
์ ๋ฃ๊ณ ,a[l+1]
, ...,a[r-2]
์ ๋ํด ๋ถํ ์๊ณ ๋ฆฌ์ฆ์ ์ํ - ์ฅ์
- ์ต์ ์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ๋ ํ๋ฅ ์ ๋ฎ์ถ์ด ์ค
- ๊ฒฝ๊ณ ํค(sentinel key)๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์
- ์ ์ฒด ์ํ ์๊ฐ์ ์ฝ 5% ๊ฐ์์ํด
void QuickSort(int a[], int l, int r)
{
int i, j, m, v;
if (r - l > 1) {
m = (l + r) / 2;
// 3๊ฐ๋ฅผ ์์๋ก ์ ํํ๊ณ , ๊ทธ ์ค์ ์ค๊ฐ๊ฐ์ pivot์ผ๋ก ์ ํํ๋ ์ฝ๋
if (a[l] > a[m]) swap(a, l, m);
if (a[l] > a[r]) swap(a, l, r);
if (a[m] > a[r]) swap(a, m, r);
swap(a, m, r-1);
// ์ฌ๊ธฐ์๋ถํฐ
v = a[r-1]; i = l; j = r-1;
for (;;) {
while (a[++i] < v);
while (a[--j] > v);
if (i >= j) break;
swap(a, i, j);
}
swap(a, i, r-1);
// ์ฌ๊ธฐ๊น์ง๋ ๋์ผ
QuickSort(a, l, i-1);
QuickSort(a, i+1, r);
}
else if (a[l] > a[r]) swap(a, l, r);
}
- ํฉ๋ณ ์ ๋ ฌ : ๋ถํ -์ ๋ณต (divide-and-conquer)
- ์ฒ์์ ํ์ผ์ ๋ ๋ถ๋ถ์ผ๋ก ๋ถํ ํ๊ณ ๋์, ๊ฐ๊ฐ์ ๋ถ๋ถ์ ๊ฐ๋ณ์ ์ผ๋ก ์ ๋ณตํจ
- Stable !
- ํต ์ ๋ ฌ : ์ ๋ณต-๋ถํ (conquer-and-divide)
- ์ํ ํธ์ถ์ด ์ด๋ฃจ์ด์ง๊ธฐ ์ ์ ๋๋ถ๋ถ์ ์์ ์ด ์ํ
- Stable ?
- ์ฝ์
์ ๋ ฌ์ ๊ฐ๋จํ๊ฒ ๋ณํ
- k๊ฐ์ ์๋ธ๋ฆฌ์คํธ๋ก ๋ถํ ํ์ฌ ์ฝ์ ์ ๋ ฌ
- ๋ฉ๋ฆฌ ๋จ์ด์ง ์์๋ผ๋ฆฌ ๊ตํ์ด ๊ฐ๋ฅํ๊ฒ ํ์ฌ ์ ๋ ฌ ์๋๋ฅผ ํฅ์์ํด
- h-์ ๋ ฌ ํ์ผ : ๋ชจ๋ h๋ฒ์งธ ์์๋ฅผ ์ ๋ ฌํ ํ์ผ
- ์ฆ๊ฐ ์์์ ์ (๊ฐ๊ฒฉ) : ..., 1093, 364, 121, 40, 13, 4, 1
- ํ์, ์ง์๊ฐ ๋ฐ๋ณต๋๋ ๊ฒ์ด ์ข์
- ์) ์ฆ๊ฐ์:
h = 3*h + 1
, ๊ฐ์์:h = h/3
- ํน์ง
- ์์ด h๊ฐ 1, 4, 13, 40, ...์ผ๋, ์ ์ ๋ ฌ์ ๋น๊ต ํ์๋
$N^{3/2}$ ์ ๋์ง ์์ - ์์ ์ ์ธ ์ ์๋ฆฌ ์ ๋ ฌ
- ์์ด h๊ฐ 1, 4, 13, 40, ...์ผ๋, ์ ์ ๋ ฌ์ ๋น๊ต ํ์๋
ShellSort(a[], n)
for (h โ 1; h < n; h โ 3*h+1) do { }; // ์ฒซ ๋ฒ์งธ h ๊ฐ ๊ณ์ฐ
for ( ; h > 0; h โ h/3) do { // h ๊ฐ์ ๊ฐ์์ํค๋ฉฐ ์งํ
for (i โ h + 1; i โค n; i โ i+1) do {
v โ a[i];
j โ i;
while (j > h and a[j-h] > v) do {
a[j] โ a[j-h];
j โ j-h;
} // while
A[j] โ v;
} // for
} // for
end ShellSort()
-
$O(n^{2})$ (worst known worst case gap sequence) -
$O(n \log n)$ (most gap sequences) -
$O(n \log ^{2} n)$ (best known worst case gap sequence)
Heap Sort | GeeksforGeeks Youtube
-
ํํ(heap)๋ฅผ ์ด์ฉํด ์ ๋ ฌ
- ์ ๋ ฌํ ์์๋ฅผ ๋ชจ๋ ๊ณต๋ฐฑ ํํ์ ํ๋์ฉ ์ฝ์
- ํ ์์์ฉ ์ญ์ โ ์ ์ผ ํฐ ์์๊ฐ ์ญ์ ๋จ
- ์ด ์์๋ฅผ ๋ฆฌ์คํธ์ ๋ค์์๋ถํฐ ์ฐจ๋ก๋ก ์ฝ์
- ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋ ๋ฆฌ์คํธ๋ฅผ ์์ฑ
-
์ ์๋ฆฌ ์ ๋ ฌ(in-place)์ด์ง๋ง ๋ถ์์ ์ (unstable)
-
$N$ ๊ฐ์ ์์๋ฅผ ์ ๋ ฌํ๋๋ฐ$N \log N$ ๋จ๊ณ๊ฐ ํ์ํจ -
์ ๋ ฅ ๋ฐฐ์ด์ ์์์ ๋ฏผ๊ฐํ์ง ์์
-
๋ด๋ถ ๋ฃจํ๊ฐ ํต ์ ๋ ฌ๋ณด๋ค ์ฝ๊ฐ ๊ธธ์ด์ ํ๊ท ์ ์ผ๋ก ํต ์ ๋ ฌ๋ณด๋ค 2๋ฐฐ ์ ๋ ๋๋ฆผ
-
์ฐธ๊ณ : ํํ - ์ฐ์ ์์ ํ์ ์ผ์ข
-
์ฐธ๊ณ : ์์ ์ด์ง ํธ๋ฆฌ : ๋ ธ๋๋ฅผ ์ฝ์ ํ ๋ ์ผ์ชฝ๋ถํฐ ์ฐจ๋ก๋๋ก ์ฝ์ ํ๋ ํธ๋ฆฌ
HeapSort(a[])
{
n โ a.length-1; // n์ ํํ ํฌ๊ธฐ (์์์ ์)
// a[0]์ ์ฌ์ฉํ์ง ์๊ณ a[1 : n]์ ์์๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ
for (i โ n/2; i โฅ 1; i โ i-1) do // ๋ฐฐ์ด a[]๋ฅผ ํํ๋ก ๋ณํ
heapify(a, i, n); // i๋ ๋ด๋ถ ๋
ธ๋
for (i โ n-1; i โฅ 1; i โ i-1) do { // ๋ฐฐ์ด a[]๋ฅผ ํํ๋ก ๋ณํ
temp โ a[1]; // a[1]์ ์ ์ผ ํฐ ์์
a[1] โ a[i+1]; // a[1]๊ณผ a[i+1]์ ๊ตํ
a[i+1] โ temp;
heapify(a, 1, i);
}
}
end heapSort()
heapify(a[], h, m)
{
// ๋ฃจํธ h๋ฅผ ์ ์ธํ h์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ ํํ
// ํ์ฌ ์์ ์ผ๋ก ๋
ธ๋์ ์ต๋ ๋ ๋ฒจ ์์ ๋ฒํธ๋ m
v โ a[h];
for (j โ 2*h; j โค m; j โ 2*j) do {
if (j < m and a[j] < a[j+1]) then j โ j+1;
// j๋ ๊ฐ์ด ํฐ ์ผ์ชฝ ๋๋ ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋
if (v โฅ a[j]) then exit;
else a[j/2] โ a[j]; // a[j]๋ฅผ ๋ถ๋ชจ ๋
ธ๋๋ก ์ด๋
}
a[j/2] โ v;
}
end heapify()
- ๊ณ์ ์ ๋ ฌ
- ์ฅ์
- ์๊ฐ ๋ณต์ก๋๊ฐ
$O(n)$ ์ด๋ค. - ๋น๊ต ๊ธฐ๋ฐ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋นํด ๋น ๋ฅด๋ค.
- ์๊ฐ ๋ณต์ก๋๊ฐ
- ๋จ์
- N์ ๋น๋กํ๋ ์ถ๊ฐ ๊ธฐ์ต์ฅ์๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ ์ ์๋ฆฌ ์ ๋ ฌ์ ์๋๋ค.
- N์ ๋ฒ์๊ฐ ํฌ๋ฉด ๊ณต๊ฐ์ ๋ญ๋น๊ฐ ์ฌํด์ง๋ค.
- ์ค๋ณต์ด ๋์ด ์์ง ์๋ค๋ฉด, ์ฌ์ฉํ๋๋ฐ ์๋ฏธ๊ฐ ์๋ค.
- N์ ๋น๋กํ๋ ์ถ๊ฐ ๊ธฐ์ต์ฅ์๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ ์ ์๋ฆฌ ์ ๋ ฌ์ ์๋๋ค.
- ์ ์ฉ ๋ฒ์
- ์ ๋ ฅ ํค๊ฐ ์ด๋ค ๋ฒ์์ ์์ ๋ ์ ์ฉ ๊ฐ๋ฅ
- ์๋ฅผ ๋ค์ด 1๋ถํฐ k ์ฌ์ด์ ์์ ์ ์ ๋ฒ์์ ์๋ค๋ ๊ฒ์ ๋ฏธ๋ฆฌ ์๊ณ ์์ ๋์๋ง ์ ์ฉ ๊ฐ๋ฅ
- ์ ์ฒด ํค๋ฅผ ์ฌ๋ฌ ์๋ฆฌ๋ก ๋๋์ด ๊ฐ ์๋ฆฌ๋ง๋ค ๊ณ์ ์ ๋ ฌ๊ณผ ๊ฐ์ ์์ ์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ์ฌ ์ ๋ ฌํ๋ ๋ฐฉ๋ฒ
-
$d$ ์๋ฆฌ์ ์ซ์๋ค์ ๋ํ์ฌ ๊ณ์ ์ ๋ ฌ๋ก ์ ๋ ฌ (์๋ฆฟ์๋งํผ ๋บ๋บ์ด๋ฅผ ๋๋ค.) - ๊ฐ ์๋ฆฌ์๋ง๋ค$O(n)$ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฏ๋ก ์ ์ฒด๋ก๋$O(dN)$ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋๋ฐ,$d$ ๋ฅผ ์์๋ก ์ทจ๊ธํ ์ ์๋ค๋ฉด$O(n)$ ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ฒ ๋จ - ์ ์ฒด ์ ๋ ฌ ๋ฐ์ดํฐ ๊ฐ์๋งํผ์ ๊ธฐ์ต ์ฅ์์ ์ง๋ฒ ํฌ๊ธฐ๋งํผ์ ๊ธฐ์ต ์ฅ์๊ฐ ์ถ๊ฐ๋ก ํ์ํจ
- ํค๊ฐ
$m$ ์๋ฆฌ ์ซ์๋ก ๋์ด ์๋ ๊ฒฝ์ฐ$m$ ๋ฒ์ ํจ์ค๋ฅผ ๋ฐ๋ณต ์ํ -
$N$ ๊ฐ์ ์์์ ๋ํด ์ด ์ฐ์ฐ์ ์๊ฐ ๋ณต์ก๋๋$ฮ(N)$ - ์ฌ์ฉ ์ : ํ๋ฒ ๋ฐ ์ฌ๋ฒ ๊ฐ์ด ์ซ์๋ก ์ด๋ฃจ์ด์ง ๊ณ ์ ๋ฒํธ, ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ ๋ฑ
RadixSort(a[], n)
{
for (k โ 1; k โค m; k โ k+1) do { // m์ digit ์, k=1์ ๊ฐ์ฅ ์์ ์๋ฆฌ ์
for (i โ 0; i < n; i โ i+1) do {
kd โ digit(a[i], k); // k๋ฒ์งธ ์ซ์๋ฅผ kd์ ๋ฐํ
enqueue(Q[kd], a[i]); // Q[kd]์ a[i]๋ฅผ ์ฝ์
}
p โ 0;
for (i โ 0; i โค 9; i โ i+1) do {
while (Q[i] =ฬธ ร) do { // Q[i]์ ๋ชจ๋ ์์๋ฅผ a[]๋ก ์ด๋
p โ p+1;
a[p] โ dequeue(Q[i]);
}
}
}
}
end RadixSort()
CPU | GPU |
---|---|
- ๋ฒ์ฉ ์ปดํจํ | - Graphic ํ์ดํ๋ผ์ธ ์ฒ๋ฆฌ |
- ๋ฉํฐ์ฝ์ด (1~8) | - ๋ฉํฐ์ฝ์ด (์๋ฐฑ ~ ์๋ง) |
- Out-of-order control (Sophisticated control) | - In-order processing (Simple control) |
- Fancy Branch predictor | - High bandwidth data access |
- Few Arithmetic Logic Units (ALU) | - A lot of Arithmetic Logic Units (ALU) |
- Powerful ALU | - Energy efficient ALUs |
- Reduced operation latency | - Many, long latency but heavily pipelined for high throughput |
- For sequential parts where latency matters | - For parallel parts where throughput wins |
- Big cache | - Small cache |
- Thread Divergence
- different threads in the same warp (scheduling units in GPU, 32 threads) taking different conditional branches
- Warp Serialization
- different threads in the same warp competing for the same bank of shared memory
- Memory Coalescing
- different threads in the same warp accessing different cache lines
- Partition Camping
- unbalanced access to memory partitions
- Occupancy
- create a massive number of threads
- Register Pressure
- reuse data in registers
- Memory Pressure
- reuse data in shared memory
30์ธ 31๊ฐ์ ํ๋ค๊ณ ์์ํด๋ณด์.
1๋ช
์ด ์๋ํ๋ฉด ์ ๋ถ ๋์ด์ง ๊ฒ์ด๋ค.
- Bubble Sort ๊ธฐ๋ฐ์ Parallel Sorting Algorithm์ผ๋ก, Bi-tone ์ฆ, 2๊ฐ์ ํค์ ์๋ฏธํ๋ค.
- Sorting Network(์ ๋ ฌ๋ง)์ ๋ฏธ๋ฆฌ ์ ์ํด์ผ ์ฌ์ฉํ ์ ์๋ค.
In computer science, comparator networks are abstract devices built up of a fixed number of "wires", carrying values, and comparator modules that connect pairs of wires, swapping the values on the wires if they are not in a desired order.
Such networks are typically designed to perform sorting on fixed numbers of values, in which case they are called sorting networks.
"Sorting network" From Wikipedia
- ์๋ฒฝํ๊ฒ ๋ณ๋ ฌ์ ์๋์ง๋ง, ํน์ ์์ ์์๋ ๊ตํ์ด ๋์์ ์ผ์ด๋๋ฏ๋ก, ๋ณ๋ ฌ์ด๋ผ๊ณ ํ ์ ์๋ค.
- Analysis
-
$O (n\log^2 n)$ comparators (๋น๊ตํ์) -
$O( \log ^{2} n)$ parallel time
-
- Space complexity
$O (n\log^2 n)$
- Odd-Even Transposition Sort๋ Bubble Sort ๊ธฐ๋ฐ์ parallel sorting algorithm์ด๋ค.
- a.k.a. Brick Sort, Parity Sort
- The Odd-Even Merge Sorting Network for Keys
- Analysis
-
$O( \log ^{2} n)$ parallel time- Worst-case performance -
$O( \log ^{2} n)$ parallel time - Best-case performance -
$O( \log ^{2} n)$ parallel time - Average performance -
$O( \log ^{2} n)$ parallel time - Worst-case space complexity -
$O(n \log ^{2} n)$ non-parallel time
- Worst-case performance -
-
- Faster than other sorting networks that have a complexity of
$O(n \log ^{2} n)$ , e.g. bitonic sort and shellsort
n | odd-even mergesort |
bitonic sort | shellsort |
---|---|---|---|
4 | 5 | 6 | 6 |
16 | 63 | 80 | 83 |
64 | 543 | 672 | 724 |
256 | 3839 | 4608 | 5106 |
1024 | 24063 | 28160 | 31915 |