알고리즘과 친해지기 (8) - 선택 정렬

몽슈뜨·2022년 11월 24일
0


  • 선택 정렬
    이번에는 선택 정렬과는 조금 느낌이 다릅니다!

    선택 정렬이 전체에서 최솟값을 "선택" 하는 거 였다면,
    삽입 정렬은 전체에서 하나씩 올바른 위치에 "삽입" 하는 방식입니다!

    선택 정렬은 현재 데이터의 상태와 상관없이 항상 비교하고 위치를 바꾸지만,
    삽입 정렬은 필요할 때만 위치를 변경하므로 더 효율적인 방식입니다!

    이미 키 순으로 정렬된 사람들이 일렬로 쭉~ 서 있는데,

    다음 원소가 그 정렬된 사람들 사이를 비집고 들어가면서

    아 여기가 내 자리구나! 하면서 삽입하며 정렬하는 방식입니다.

    한 번 예시를 통해 봐볼게요!

[4, 6, 2, 9, 1]  # 정렬되지 않은 배열

1단계 : [4, 6, 2, 9, 1] 
        4는 현재 정렬되어 있는 부대원입니다. 
			  그럼 이제 새로운 신병인 6을 받습니다.
        4, 6 이 되는데 4 < 6 이므로 그대로 냅둡니다.
       [4, 6, 2, 9, 1] 이렇게요!

자, 그러면 이제 한 바퀴를 돌렸죠?
이 과정에서 새로운 부대원인 4, 6은 현재 정렬된 상태입니다!
이처럼, 삽입 정렬은 한 바퀴가 돌 때마다 정렬된 상태가 됩니다.
끝까지 한 번 반복해볼게요!

2단계 : [4, 6, 2, 9, 1]
        4, 6 은 현재 정렬되어 있는 부대원입니다.
        그럼 이제 새로운 신병인 2를 받습니다.
        4, 6, 2 가 되는데 6 > 2 이므로 둘을 변경합니다!
        4, 2, 6 가 되는데 4 > 2 이므로 둘을 변경합니다!
       [2, 4, 6, 9, 1] 이렇게요!

3단계 : [2, 4, 6, 9, 1]
        2, 4, 6 은 현재 정렬되어 있는 부대원입니다.
        그럼 이제 새로운 신병인 9를 받습니다.
        2, 4, 6, 9 가 되는데 6 < 9 이므로 그대로 냅둡니다.
       [2, 4, 6, 9, 1] 이렇게요!

4단계 : [2, 4, 6, 9, 1]
        2, 4, 6, 9 은 현재 정렬되어 있는 부대원입니다.
        그럼 이제 새로운 신병인 1을 받습니다.
        2, 4, 6, 9, 1 가 되는데 9 > 1 이므로 둘을 변경합니다!
        2, 4, 6, 1, 9 가 되는데 6 > 1 이므로 둘을 변경합니다!
        2, 4, 1, 6, 9 가 되는데 4 > 1 이므로 둘을 변경합니다!
        2, 1, 4, 6, 9 가 되는데 2 > 1 이므로 둘을 변경합니다!
       [1, 2, 4, 6, 9] 이렇게요!

자, 모두 정렬이 되었습니다! 어떠신가요? 감이 좀 오시나요?
  • ❓ Q.
    다음과 같이 숫자로 이루어진 배열이 있을 때, 오름차순으로 삽입 정렬을 이용해서 정렬하시오.

    input = [4, 6, 2, 9, 1]
    
    def insertion_sort(array):
       # 이 부분을 채워보세요!
       return
    
    insertion_sort(input)
    print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
    
    print("정답 = [4, 5, 7, 7, 8] / 현재 풀이 값 = ",insertion_sort([5,8,4,7,7]))
    print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",insertion_sort([3,-1,17,9]))
    print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",insertion_sort([100,56,-3,32,44]))
    • 💡 내 코드

      input = [4, 6, 2, 9, 1]
      
      
      def insertion_sort(array):
        # 이 부분을 채워보세요!
        return
      
      
      insertion_sort(input)
      print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
      
      print("정답 = [4, 5, 7, 7, 8] / 현재 풀이 값 = ",insertion_sort([5,8,4,7,7]))
      print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",insertion_sort([3,-1,17,9]))
      print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",insertion_sort([100,56,-3,32,44]))
    • 🚩 해결방법
      위에서 이야기했던 로직 그대로 코드에 옮기면 됩니다!

      우선, 반복되는 구조라서 반복문을 써야 하는데, 어떤 식으로 반복하고 있나요?

      1번째 : [4, 6, 2, 9, 1]
      ← 비교!
      2번째 : [4, 6, 2, 9, 1]
      ← ← 비교!
      3번째 : [2, 4, 6, 9, 1]
      ← ← ← 비교!
      4번째 : [2, 4, 6, 9, 1]
      ← ← ← ← 비교!

      즉, 1만큼 비교했다가, 1개씩 늘어나면서 반복하게 됩니다.
      이 반복문을 구현하려면 아래처럼 작성하면 됩니다!

      for i in range(1, 5):   # Q. 여기서 왜 range(5) 가 아니라 range(1, 5) 일까요?
      		for j in range(i):  # A. 삽입 정렬의 0 번째 인덱스는 정렬된 상태라고
      		    print(i - j)    #    판단할 수 있기 때문에, 첫 번째 인덱스를 비교하지 않고   넘어갑니다.

      내부 반복문 안에서, 만약
      array[i - j - 1] > array[i - j] 라면 두 값을 변경해주고,
      아니라면 나가면 됩니다!

      나가는 이유는? 이미 앞에 있는 원소들이 정렬이 되었으므로
      더 비교할 이유가 없기 때문입니다.

      위의 예시 중 3단계에 해당합니다.

      3단계 : [2, 4, 6, 9, 1]

      신병인 9는 앞의 부대원인 6과 비교하지만 6 < 9 이기 때문에 그대로 냅둬도 됩니다.
      이후에 9와 4를 비교할 필요가 있을까요? 없습니다!
      앞에 원소들은 이미 6보다 낮은 숫자들로 정렬되어 있을테니까요!

      input = [4, 6, 2, 9, 1]
      
      def insertion_sort(array):
         n = len(array)
         for i in range(1, n):
             for j in range(i):
                 if array[i - j - 1] > array[i - j]:
                     array[i - j - 1], array[i - j] = array[i - j], array[i - j - 1]
                 else:
                     break
         return array
      
      insertion_sort(input)
      print(input)
      
      print("정답 = [4, 5, 7, 7, 8] / 현재 풀이 값 = ",insertion_sort([5,8,4,7,7]))
      print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",insertion_sort([3,-1,17,9]))
      print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",insertion_sort([100,56,-3,32,44]))
profile
개발자되면 맥북사줄께

0개의 댓글