์๋ํ๋ฉด ๊ฐ๊ฒฉ(gap)์ด ๋๋ฌด ์ ์ผ๋ฉด ๊ฑด๋ ๋ฐ๋ ๊ฐ๊ฒฉ์ด ์ข์์ง๋ค. ์ฆ, pass ์๋๊ฐ ๋๋ ค์ง๋ค๋ ๋ป์ด๋ค.
๋ฐ๋๋ก ๊ฐ๊ฒฉ์ด ํฌ๋ฉด ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋์ ๋ง์ ์ฌ๋๋ค์ด ํ๊ท ์ ์ผ๋ก ์ข์ ๊ฐ๊ฒฉ๋ค์ ๋ด๋์๋๋ฐ, ์ด๋ฅผ ๊ฐญ ์ํ์ค(Gap Sequences)๋ผ๊ณ ํ๋ค.
์๋ ๊ธ์ ๋ณด๋ฉด ๋ง์ ๊ฐญ ์ํ์ค๋ค์ด ์๋ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
Shellsort
๐ ์ฝ์ ์ ๋ ฌ์ ์ด๊ธฐ๋ฆฌ์คํธ๊ฐ "๊ฑฐ์ ์ ๋ ฌ"๋์ด ์์ ๊ฒฝ์ฐ ํจ์จ์ ์ด๋ค.
์ฐ์์ ์ด์ง ์์ ๋ถ๋ถ ๋ฆฌ์คํธ์์ ์๋ฃ์ ๊ตํ์ด ์ผ์ด๋๋ฉด ๋ ํฐ ๊ฑฐ๋ฆฌ๋ฅผ ์ด๋ํ๋ค. ๋ฐ๋ผ์ ๊ตํ๋๋ ์์๋ค์ด ์ฝ์ ์ ๋ ฌ๋ณด๋ค๋ ์ต์ข ์์น์ ์์ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋ค.
๋ถ๋ถ ๋ฆฌ์คํธ๋ ์ด๋ ์ ๋ ์ ๋ ฌ์ด ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋ถ๋ถ ๋ฆฌ์คํธ์ ๊ฐ์๊ฐ 1์ด ๋๊ฒ ๋๋ฉด ์ ธ ์ ๋ ฌ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ์ ์ ๋ ฌ์ ์ํํ๋ ๊ฒ์ด์ง๋ง ์ฝ์ ์ ๋ ฌ๋ณด๋ค ๋์ฑ ๋น ๋ฅด๊ฒ ์ํ๋๋ค.
gap Sequence = {1, 4, 10, 23, 57, 132, 301, 701, 1750}
1750 ์ดํ๋ก๋ Gn = (Gn - 1) * 2.25
๋ก ํํ
์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค
private final static int[] gap =
{ 1, 4, 10, 23, 57, 132, 301, 701, 1750, 3937,
8858, 19930, 44842, 100894, 227011, 510774,
1149241, 2585792, 5818032, 13090572, 29453787,
66271020, 149109795, 335497038, 754868335, 1698453753}; // ๊ฐญ์ ๋ด๊ณ ์๋ ๋ฐฐ์ด
public class Shell_Sort {
private final static int[] gap =
{ 1, 4, 10, 23, 57, 132, 301, 701, 1750, 3937,
8858, 19930, 44842, 100894, 227011, 510774,
1149241, 2585792, 5818032, 13090572, 29453787,
66271020, 149109795, 335497038, 754868335, 1698453753}; // ๊ฐญ์ ๋ด๊ณ ์๋ ๋ฐฐ์ด
public static void shell_sort(int[] a) {
shell_sort(a, a.length);
}
// ๋งจ ์ฒ์ gap์ ์ฐธ์กฐํ ์ธ๋ฑ์ค๋ฅผ ๊ตฌํ๋ ๋ฉ์๋
private static int getGap(int length) {
int index = 0;
// ์ต์ํ ๋ถ๋ถ ๋ฐฐ์ด์ ์์๊ฐ 2๊ฐ์ฉ์ ๋น๊ต๋๋๋ก ๋๋ ์ค๋ค.
int len = (int)(length / 2.25); // โ Gn = (Gn - 1) * 2.25
while (gap[index] < len) {
index++;
}
return index;
}
private static void shell_sort(int[] a, int size) {
int index = getGap(size); // ์ฒซ gap์ ์ฌ์ฉํ index
// gap[index] ๊ฐ๋ถํฐ gap[0] ๊น์ง ๋ฐ๋ณตํ๋ค.
for (int i = index; i >= 0; i--) {
for (int j = 0; j < gap[i]; j++) {
insertion_sort(a, j, size, gap[i]); // ๊ฐ ๋ถ๋ถ ๋ฆฌ์คํธ์ ๋ํด ์ฝ์
์ ๋ ฌ์ ํ๋ค.
}
}
}
/**
* @param a ๋ฐฐ์ด
* @param start ๋ถ๋ถ ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์ ์ธ๋ฑ์ค
* @param size ๋ฐฐ์ด์ ์ ์ฒด ํฌ๊ธฐ
* @param gap ํ์ฌ gap
*/
private static void insertion_sort(int[] a, int start, int size, int gap) {
// ๋ถ๋ถ ๋ฐฐ์ด์ ๋ ๋ฒ์งธ ์์๋ถํฐ size๊น์ง ๋ฐ๋ณตํ๋ค. (gap ๊ฐ์ฉ ๊ฑด๋๋)
for (int i = start + gap; i < size; i += gap) {
int target = a[i];
int j = i - gap;
// ํ๊ฒ ์์๊ฐ ์ด์ ์ ์์๋ณด๋ค ์์ ๋ ๊น์ง ๋ฐ๋ณต
while (j >= start && target < a[j]) {
a[j + gap] = a[j]; // ์ด์ ์์๋ฅผ ํ ์นธ์ฉ ๋ค๋ก ๋ฏธ๋ฃฌ๋ค.
j -= gap;
}
/*
* ์ ๋ฐ๋ณต๋ฌธ์์ ํ์ถ ํ๋ ๊ฒฝ์ฐ ์์ ์์๊ฐ ํ๊ฒ๋ณด๋ค ์๋ค๋ ์๋ฏธ์ด๋ฏ๋ก
* ํ๊ฒ ์์๋ j๋ฒ์งธ ์์ ๋ค์ ์์ผํ๋ค.
* ๊ทธ๋ฌ๋ฏ๋ก ํ๊ฒ์ j + gap ์ ์์นํ๊ฒ ๋๋ค.
*/
a[j + gap] = target;
}
}
}
public class Shell_Sort {
private final static int[] gap =
{ 1, 4, 10, 23, 57, 132, 301, 701, 1750, 3937,
8858, 19930, 44842, 100894, 227011, 510774,
1149241, 2585792, 5818032, 13090572, 29453787,
66271020, 149109795, 335497038, 754868335, 1698453753}; // ๊ฐญ์ ๋ด๊ณ ์๋ ๋ฐฐ์ด
public static void shell_sort(int[] a) {
shell_sort(a, a.length);
}
// ๋งจ ์ฒ์ gap์ ์ฐธ์กฐ ํ ์ธ๋ฑ์ค๋ฅผ ๊ตฌํ๋ ๋ฉ์๋
private static int getGap(int length) {
int index = 0;
// ์ต์ํ ๋ถ๋ถ ๋ฐฐ์ด์ ์์๊ฐ 2๊ฐ์ฉ์ ๋น๊ต ๋๋๋ก ๋๋ ์ค๋ค.
int len = (int)(length / 2.25);
while (gap[index] < len) {
index++;
}
return index;
}
private static void shell_sort(int[] a, int size) {
int gapIndex = getGap(size);
// ๊ฐญ์ด 1์ด ๋ ๋๊น์ง ๋ฐ๋ณต
while(gapIndex >= 0) {
int step = gap[gapIndex--]; // ํ์ฌ gap(step)
/*
* <--- ์ฝ์
์ ๋ ฌ ๊ณผ์ --->
*
* ๊ฐ ๋ถ๋ถ๋ฆฌ์คํธ์ ๋ ๋ฒ์งธ ์์์ ์ธ๋ฑ์ค ๋ถํฐ ์ํํ๋ค.
* ์๋ฅผ ๋ค์ด, step์ด 3์ผ ๋ arr[0], arr[1], arr[2] ๋
* ์ด์ ์์์ ๋น๊ตํ ๊ฒ์ด ์๋ค.
* ๊ทธ๋ฌ๋ฏ๋ก step๋ถํฐ ์ํํ๋ค.
*/
for(int i = step; i < size; i++) {
/*
* j๋ target ์์๊ฐ ๋๋ฉฐ ํ์ฌ ์์(target) a[j]๊ฐ ์ด์ ์์ a[j - step]๋ณด๋ค
* ์์ ๋ ๊น์ง ๋ฐ๋ณตํ๋ค.
*/
for (int j = i; j >= step && a[j] < a[j - step]; j -= step) {
/*
* ํ์ฌ(target) ์์์ ์ธ๋ฑ์ค(j)์ ์ด์ ์ ์์(j-step)์ ์ธ๋ฑ์ค์ ์๋
* ์์์ ๊ฐ์ ๊ตํํ๋ค.
*/
swap(a, j, j - step);
}
}
}
}
private static void swap(int[] a, int i, int j) {
int swap = a[i];
a[i] = a[j];
a[j] = swap;
}
}
์ฐธ๊ณ
[์๊ณ ๋ฆฌ์ฆ] ์ ธ ์ ๋ ฌ(shell sort)์ด๋ - Heee's Development Blog
์๋ฐ [JAVA] - ์ ธ ์ ๋ ฌ (Shell Sort)