๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Programming/์ทจ์—…์ค€๋น„&CS Study

[CS์Šคํ„ฐ๋”” #01] ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜

 

 

 

๐Ÿ’ป ์•Œ๊ณ ๋ฆฌ์ฆ˜: Algorithm

 

์„ ํƒ ์ •๋ ฌ (Selection Sort)

 

   "๊ฐ€์žฅ ์ž‘์€ ๋ฐ์ดํ„ฐ๋ฅผ ์„ ํƒํ•˜์—ฌ ๋งจ ์•ž์˜ ๋ฐ์ดํ„ฐ์™€ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พผ๋‹ค"

   i๋ฒˆ์งธ ์œ„์น˜์˜ ๊ฐ’์— ๋Œ€ํ•˜์—ฌ i+1๋ฒˆ์งธ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์›์†Œ๊นŒ์ง€ ๋น„๊ตํ•˜์—ฌ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์ฐพ์•„๋‚ด ํ˜„์žฌ i๋ฒˆ์งธ ์œ„์น˜์˜ ๊ฐ’๊ณผ ์ž๋ฆฌ๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š” ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฆ‰ 0~i-1๊นŒ์ง€ ์ด๋ฏธ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ฐพ์•„๋‚ธ ์ •๋ฆฌ๋œ ๊ฐ’๋“ค์€ ๋‘๊ณ , ํ˜„์žฌ ์œ„์น˜์— ๋“ค์–ด๊ฐˆ ์ตœ์†Œ๊ฐ’์„ ์ •๋ ฌ์ด ์•ˆ๋œ ์›์†Œ๋“ค ์‚ฌ์ด์—์„œ ์ฐพ์•„๋‚ด ์„ ํƒํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ตœ์†Œ๊ฐ’์„ ์ฐพ๋Š” ์ „์ฒด ํƒ์ƒ‰์„ ๋ชจ๋“  ์›์†Œ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ Time Complexity๋Š” O(N^2)์ด ๋œ๋‹ค.

 

 >> ํŠน์ง•

  • ๊ฐ€์žฅ ์›์‹œ์ ์ธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
  • ์‹œ๊ฐ„๋ณต์žก๋„: O(N^2)

 >> ์†Œ์Šค์ฝ”๋“œ

void selectionSort(int arr[], int size) {
    int minIndex;
    int i, j;
    for (i = 0; i < size - 1; i++) {
        minIndex = i;
        for (j = i + 1; j < size; j++) 
            if (arr[j] < arr[minIndex])
                minIndex = j;
         
        swap(&arr[i], &arr[minIndex]);
    }
}
#ํŒŒ์ด์ฌ
arr = [1, 5, 3, 4, 2, 88, 4, 7, -1, 0]
n = len(arr)

for i in range(0, n-1):
    least = i
    for j in range (i+1, n):
        if arr[least] > arr[j]:
            least = j
    arr[i], arr[least] = arr[least], arr[i]

 

 

 

 

๋ฒ„๋ธ” ์ •๋ ฌ (Bubble Sort)

 

 ์ธ์ ‘ํ•œ ๋‘ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„๊ตํ•ด๊ฐ€๋ฉฐ ์ •๋ ฌ์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

   ํ•œ ๋ฒˆ์˜ ์—ฐ์‚ฐ๋งˆ๋‹ค ์ •๋ ฌ์ด ์•ˆ๋œ ๋ชจ๋“  ๊ฐ’๋“ค์— ๋Œ€ํ•ด ์ธ์ ‘ ๋น„๊ต๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๊ทธ ์ค‘์—์„œ ๊ฐ€์žฅ ํฐ ๊ฐ’์ด ๋ฐฐ์—ด์˜ ๋งจ ๋์œผ๋กœ ์ •๋ ฌ๋œ๋‹ค. ์ด์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์„ n๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฏ€๋กœ Time Complexity๋Š” O(N^2)์ด ๋œ๋‹ค.

 

 >> ํŠน์ง•

  • ์‹œ๊ฐ„๋ณต์žก๋„: O(N^2)

 >> ์†Œ์Šค์ฝ”๋“œ

//์ž๋ฐ”
void bubbleSort(int arr[], int size) {
    int i, j;
    for (i = size - 1; i>0; i--) 
        for (j = 0; j<i; j++) 
            if (arr[j]<arr[j + 1]) 
                swap(arr[j], arr[j + 1]);
}
#ํŒŒ์ด์ฌ
arr = [1, 5, 3, 4, 2, 88, 4, 7, -1, 0]
n = len(arr)

for i in range(n-1):
    for j in range (n-1-i):
        if arr[j] > arr[j+1]:
            arr[j], arr[j+1] = arr[j+1], arr[j]

 

 

 

 

์‚ฝ์ž… ์ •๋ ฌ (Insertion Sort)

 

 "๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๋ฉฐ, ์ ์ ˆํ•œ ์œ„์น˜์— ์‚ฝ์ž…ํ•œ๋‹ค."

 n๊ฐœ์˜ ์›์†Œ๋ฅผ ๊ฐ€์ง„ ๋ฐฐ์—ด์„ ์ •๋ฆฌํ•  ๋•Œ, i๋ฒˆ์งธ๋ฅผ ์ •๋ ฌํ•  ์ˆœ์„œ๋ผ๊ณ  ํ•œ๋‹ค๋ฉด 0๋ถ€ํ„ฐ i-1๋ฒˆ์งธ๊นŒ์ง€๋Š” ์ •๋ ฌ๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฐ€์ • ํ•˜์— i๋ฒˆ์งธ ์›์†Œ๊ฐ€ ๋“ค์–ด๊ฐˆ ์œ„์น˜๋ฅผ ์ฐพ๋Š” ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ด ๊ณผ์ •์„ ๋ฐฐ์—ด์˜ ๋งˆ์ง€๋ง‰ ์›์†Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์ฃผ๋ฏ€๋กœ Time Complexity๋Š” O(N^2)์ด ๋œ๋‹ค.

 

 >> ํŠน์ง•

  •  ํ•„์š”ํ•  ๋•Œ๋งŒ ์œ„์น˜๋ฅผ ๋ฐ”๊พธ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฑฐ์˜ ์ •๋ ฌ๋˜์–ด ์žˆ์„ ๋•Œ ํšจ๊ณผ์ ์ด๋‹ค.
  •  ์‹œ๊ฐ„๋ณต์žก๋„: O(n^2)
  •  ๋‹จ, ๊ฑฐ์˜ ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋ผ๋ฉด ๋ฃจํ”„ ์•ˆ์˜ ๋ฐ˜๋ณต๋ฌธ์ด 1ํšŒ๋งŒ ์‹ค์‹œ๋˜๊ณ  ๋ง๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•˜์—ฌ O(N)์˜ ์„ฑ๋Šฅ์„ ๋ณด์ธ๋‹ค. 

 >> ์†Œ์Šค์ฝ”๋“œ

void insertionSort(int arr[], int size) {
    int i, j,key;
 
    for (i = 1; i < size; i++) {
        key = arr[i];
        j = i - 1;
        while (j >= 0&&arr[j]>key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}
#ํŒŒ์ด์ฌ
arr = [1, 5, 3, 4, 2, 88, 4, 7, -1, 0]
n = len(arr)

for i in range(1, n):
    key = arr[i]
    j = i-1
    while j >= 0 and arr[j] > key:
        arr[j+1] = arr[j]
        j = j-1
    arr[j+1] = key

 

 

 

 

ํ€ต ์ •๋ ฌ (Quick Sort)

 

   "๊ธฐ์ค€์ด ๋˜๋Š” ํ”ผ๋ฒ—(Pivot)์„ ์ •ํ•œ ๋’ค ํฐ์ˆ˜์™€ ์ž‘์€ ์ˆ˜๋ฅผ ๊ตํ™˜ํ•œ ํ›„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค."

   ํ”ผ๋ฒ—์„ ์–ด๋–ป๊ฒŒ ์ •ํ•˜๋Š” ์ง€๋ฅผ ๋ฏธ๋ฆฌ ๋ช…์‹œํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋ณดํ†ต '๋ฆฌ์ŠคํŠธ์—์„œ ์ฒซ ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋ฅผ ํ”ผ๋ฒ—์œผ๋กœ ์ •ํ•œ๋‹ค'๋Š” ํ˜ธ์–ด ๋ถ„ํ•  ๋ฐฉ์‹์„ ๊ธฐ์ค€์œผ๋กœ ์‚ผ๋Š”๋‹ค.

   ํ”ผ๋ฒ—์„ ์„ค์ •ํ•œ ๋’ค์—๋Š” ์™ผ์ชฝ๋ถ€ํ„ฐ ํ”ผ๋ฒ—๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ณ , ์˜ค๋ฅธ์ชฝ๋ถ€ํ„ฐ ํ”ผ๋ฒ—๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์œผ๋ฉฐ ์„œ๋กœ ๊ตํ™˜ํ•œ๋‹ค. 

 

 >> ํŠน์ง•

  • ํŒŒ์ด์ฌ์ด๋‚˜ ์ž๋ฐ”์—์„œ ์ •๋ ฌ ๋‚ด์žฅํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ์ด ๋œ๋‹ค.
  • ์žฌ๊ท€ํ•จ์ˆ˜์™€ ๋™์ž‘ ์›๋ฆฌ๊ฐ€ ๊ฐ™๋‹ค.
  • ์‹œ๊ฐ„๋ณต์žก๋„: ํ‰๊ท ์ ์œผ๋กœ O(N^2), ์ตœ์•…์˜ ๊ฒฝ์šฐ O(N^2)์ด๋‹ค. ํ”ผ๋ด‡๊ฐ’์˜ ์„ ํƒ์— ๋”ฐ๋ผ ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง„๋‹ค. 
  • ์ผ๋ฐ˜์ ์œผ๋กœ ์›์†Œ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ ์–ด์งˆ์ˆ˜๋ก ๋‚˜์œ ์ค‘๊ฐ„๊ฐ’์ด ์„ ํƒ๋  ํ™•๋ฅ ์ด ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ์—, ์›์†Œ์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ํ€ต ์ •๋ ฌ์— ๋‹ค๋ฅธ ์ •๋ ฌ์„ ํ˜ผํ•ฉํ•ด์„œ ์“ฐ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.
  • ๋ณ‘ํ•ฉ ์ •๋ ฌ์€ ํ•ญ์ƒ ์ •์ค‘์•™์„ ๊ธฐ์ค€์œผ๋กœ ๋‹จ์ˆœ ๋ถ„ํ•  ํ›„ ๋ณ‘ํ•ฉ ์‹œ์ ์—์„œ์˜ ๊ฐ’์˜ ๋น„๊ต ์—ฐ์‚ฐ์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฐ˜๋ฉด์—, ํ€ต ์ •๋ ฌ์€ ๋ถ„ํ•  ์‹œ์ ๋ถ€ํ„ฐ ๋น„๊ต์—ฐ์‚ฐ์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์ดํ›„ ๋ณ‘ํ•ฉ์— ๋“ค์–ด๊ฐ€๋Š” ๋น„์šฉ์ด ๋งค์šฐ ์ ๊ฑฐ๋‚˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ์•„์˜ˆ ๋ณ‘ํ•ฉ์„ ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

>> ์†Œ์Šค ์ฝ”๋“œ

//์ž๋ฐ”
public class QuickSorter {
    public static List<Integer> quickSort(List<Integer> list) {
        if (list.size() <= 1) return list;
        int pivot = list.get(list.size() / 2);

        List<Integer> lesserArr = new LinkedList<>();
        List<Integer> equalArr = new LinkedList<>();
        List<Integer> greaterArr = new LinkedList<>();

        for (int num : list) {
            if (num < pivot) lesserArr.add(num);
            else if (num > pivot) greaterArr.add(num);
            else equalArr.add(num);
        }

        return Stream.of(quickSort(lesserArr), equalArr, quickSort(greaterArr))
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }
}
#ํŒŒ์ด์ฌ
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    lesser_arr, equal_arr, greater_arr = [], [], []
    for num in arr:
        if num < pivot:
            lesser_arr.append(num)
        elif num > pivot:
            greater_arr.append(num)
        else:
            equal_arr.append(num)
    return quick_sort(lesser_arr) + equal_arr + quick_sort(greater_arr)

 

 

 

 

 

๋ณ‘ํ•ฉ ์ •๋ ฌ (Merge Sort)

 

 Divide and Conquer. ์ฆ‰, ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ์šฐ์„  ์ž‘๊ฒŒ ์ชผ๊ฐœ๊ณ  ๋‚œ ํ›„, ๋‹ค์‹œ ์กฐํ•ฉํ•˜์—ฌ ์›๋ž˜์˜ ๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š” ๋ฐฉ์‹์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

 ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์„ ์ตœ์†Œ๊ธธ์ด๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ ์ ˆ๋ฐ˜์œผ๋กœ ๋ถ„ํ• ํ•˜์—ฌ ๋ถ€๋ถ„ ๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜๋ˆ„๊ณ , ์ธ์ ‘ํ•œ ๋ถ€๋ถ„ ๋ฐฐ์—ด๋ผ๋ฆฌ ์ •๋ ฌํ•˜์—ฌ ํ•ฉ์น˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

 

 >> ํŠน์ง•

  • ์‹œ๊ฐ„๋ณต์žก๋„: O(N*logN)
  • ์ ˆ๋ฐ˜์”ฉ ๋ถ„ํ• ํ•˜๋Š” ๊ณผ์ •์—์„œ O(logN)์˜ ์‹œ๊ฐ„์ด, ๋ณ‘ํ•ฉํ•˜๋ฉฐ ๋ชจ๋“  ๊ฐ’๋“ค์˜ ์ˆœ์„œ๋ฅผ ๋น„๊ตํ•˜๋Š” O(N)์˜ ์‹œ๊ฐ„์ด ์†Œ๋ชจ๋œ๋‹ค. 
  • ๋‘ ๊ฐœ์˜ ๋ฐฐ์—ด์„ ๋ณ‘ํ•ฉํ•  ๋•Œ, ๋ณ‘ํ•ฉ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์•„ ๋†“์„ ๋ฐฐ์—ด์ด ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐ„ ๋ณต์žก๋„๋Š” O(N)์ด ๋œ๋‹ค.
  • ๋‹ค๋ฅธ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋‹ฌ๋ฆฌ, ์ธ์ ‘ํ•œ ๊ฐ’๋“ค ๊ฐ„์— ์ƒํ˜ธ ์ž๋ฆฌ ๊ต๋Œ€(swap)๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

 >> ์†Œ์Šค์ฝ”๋“œ

// ์ž๋ฐ”
public class MergeSorter {
    public static int[] sort(int[] arr) {
        if (arr.length < 2) return arr;

        int mid = arr.length / 2;
        int[] low_arr = sort(Arrays.copyOfRange(arr, 0, mid));
        int[] high_arr = sort(Arrays.copyOfRange(arr, mid, arr.length));

        int[] mergedArr = new int[arr.length];
        int m = 0, l = 0, h = 0;
        while (l < low_arr.length && h < high_arr.length) {
            if (low_arr[l] < high_arr[h])
                mergedArr[m++] = low_arr[l++];
            else
                mergedArr[m++] = high_arr[h++];
        }
        while (l < low_arr.length) {
            mergedArr[m++] = low_arr[l++];
        }
        while (h < high_arr.length) {
            mergedArr[m++] = high_arr[h++];
        }
        return mergedArr;
    }
}
# ํŒŒ์ด์ฌ
def merge_sort(arr):
    if len(arr) < 2:
        return arr

    mid = len(arr) // 2
    low_arr = merge_sort(arr[:mid])
    high_arr = merge_sort(arr[mid:])

    merged_arr = []
    l = h = 0
    while l < len(low_arr) and h < len(high_arr):
        if low_arr[l] < high_arr[h]:
            merged_arr.append(low_arr[l])
            l += 1
        else:
            merged_arr.append(high_arr[h])
            h += 1
    merged_arr += low_arr[l:]
    merged_arr += high_arr[h:]
    return merged_arr

 

 ์ตœ์ ํ™” ์ฝ”๋“œ๋„ ์žˆ์ง€๋งŒ, ์ด ๊ธ€์—์„œ๋Š” ์ด ์ •๋„๋กœ๋งŒ ์ •๋ฆฌํ•˜๊ฒ ๋‹ค.

 

 

 

 

ํž™ ์ •๋ ฌ (Heap Sort), ๊ณ„์ˆ˜ ์ •๋ ฌ (Count Sort), ๊ธฐ์ˆ˜ ์ •๋ ฌ (Radix Sort)

 ์ •๋ฆฌ ์ค‘...

 

 

 

 

 

 

 

โ“โ“โ“

  • 54321๋กœ ์ •๋ ฌ๋œ ๋ฐฐ์—ด์ด ์žˆ์„ ๋•Œ, ์ด๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ฆฌํ•˜๋ ค๋ฉด ์–ด๋–ค ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€๊ฐ€?
  • ์›์†Œ๋“ค์ด ๋žœ๋ค์œผ๋กœ ๋ฐฐ์น˜๋œ ๋ฐฐ์—ด์ด ์žˆ์„ ๋•Œ, ์–ด๋–ค ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€๊ฐ€?
  • ์ž๋ฆฟ์ˆ˜๊ฐ€ ๋ชจ๋‘ ๊ฐ™์€ ์ˆ˜๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์ด ์žˆ์„ ๋•Œ, ์–ด๋–ค ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€๊ฐ€? 

 

 

 

 

 

 

 

 

 

๐Ÿ’Ž ๐Ÿ’Ž ๐Ÿ’Ž

 

 

๏ผฐ๏ฝ๏ฝ“๏ฝ”๏ฝ…๏ฝ„ ๏ผข๏ฝ™ ๏ผณ๏ผก๏ผน

๐˜›๐˜ฉ๐˜ข๐˜ฏ๐˜ฌ๐˜ด ๐˜ง๐˜ฐ๐˜ณ ๐˜ณ๐˜ฆ๐˜ข๐˜ฅ๐˜ช๐˜ฏ๐˜จ