[ラーニング]ソートアルゴリズム


ソートの選択

  • 未処理のデータから最小のデータを選択し、
  • を最上位のデータに置き換える.
  • 並べ替えアルゴリズムはn-1個、n-2個、...1つずつ比較を繰り返す.
  • 探索範囲が縮小した.(ソートを除く)
  • 配列方式にかかわらず全体比較が行われ,時間的複雑度はO(n^2)である.
  • array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
    
    for i in range(len(array)):
        min_index = i # 가장 작은 원소의 인덱스
        for j in range(i+1, len(array)):
            if array[min_index] > array[j]:
                min_index = j
        array[i], array[min_index] = array[min_index], array[i] # 스왑
    
    print(array)
    >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    整列挿入

  • の未処理データを選択し、適切な位置
  • に挿入する.
  • 選択ソートに比べて、実装はより困難であるが、効率はより高い.
  • の一番前(左)は揃えられていて、2番目のデータはどこに入りますか.
  • 時間複雑度O(N^2)
  • は左側と比較してソートを続けます.
  • 
    #        0  1  2  3  4  5  6  7  8  9
    array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
    # j는 삽입하고자 하는 원소의 위치를 의미한다.
    for i in range(1, len(array)): # array 배열의 인덱스 1부터 (10-1=)인덱스 9 까지 반복)
        for j in range(i, 0, -1): # 인덱스 i부터 1(0 전까지니까)까지 1씩 감소하며 반복하는 문법
            if array[j] < array[j - 1]: # 왼쪽에 있는 애랑 비교했을 때 값이 더 작다면, 한 칸씩 왼쪽으로 이동
                array[j], array[j - 1] = array[j - 1], array[j] # 스왑 연산
            else: # 자기보다 작은 데이터를 만나면 그 위치에서 멈춤
                break
    print(array)
    
    >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    クイックソート

  • データムデータを設定し、ビッグデータとビッグデータの位置を変更します.
  • の大部分はプログラミングの基礎です.
  • は、第1のデータを基準データ(pivot)に設定する.
  • O(NlogN)
  • ソート後、O(N^2)->は逆にソート時に性能が低下します.

  • クイックソートコード1

    
    array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
    
    
    def quick_sort(array, start, end):
        if start >= end:
            return
        pivot = start # 첫번째 원소를 피벗 값으로 지정
        left = start+1 # 첫원소의 2번째를 왼쪽
        right = end # 마지막 값을 오른쪽으로 지정
        while(left <= right): # 엇갈릴 때까지 계속하라
            # left가 가리키는 인덱스값이 right가 가리키고 있는 인덱스값보다 크다면 반복문 나와라
            while(left <= end and array[left] <= array[pivot]): # 왼쪽은 큰수, 피벗보다 큰 데이터를 찾을 때까지 반복한다.
                left += 1 # left 인덱스값을 키우면서 살펴봄.
            while(right > start and array[right] >= array[pivot]): # 피벗보다 작은 값을 찾을 때까지 반복한다.
                right -= 1 # 끝부터 오는 거니까 -1씩해서 인덱스값을 줄이면서 탐색한다.
            if(left > right): # 엇갈렸다면 작은 데이터와 피벗을 교체
                array[right], array[pivot] = array[pivot], array[right]
            else: # 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체한다.
                array[left], array[right] = array[right], array[left]
        # 분할 이후에 왼쪽과 오른쪽 부분에서 각각 정렬을 수행한다. 재귀 함수로 표현
        quick_sort(array, start, right-1) # 왼쪽(작은수) 재귀 정렬
        quick_sort(array, right+1, end) # 오른쪽(큰수) 재귀 정렬
    
    quick_sort(array, 0, len(array) - 1)
    print(array)
    >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    クイックソートコード2

    '''
    파이썬의 장점을 살린 방식
    리스트 슬라이싱
    '''
    
    array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
    
    def quick_sort(array):
        # 리스트가 하나 이하의 원소만을 담고 있다면 종료
        if len(array) <= 1:
            return array
        pivot = array[0] # 피벗은 첫 번째 원소
        tail = array[1:] # 피벗을 제외한 리스트
    
        left_side = [x for x in tail if x <= pivot] # 분할된 왼쪽 부분
        right_side = [x for x in tail if x > pivot] # 분할된 오른쪽 부분
    
        #분할 이후 왼쪽과 오른쪽 부분에서 각각 정렬을 수행하고, 전체 리스트 반환
        return quick_sort(left_side) + [pivot] + quick_sort(right_side)
    
    print(quick_sort(array))
    >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    ソート数

  • データサイズの範囲は限られており、整数で表すことができる.
  • O(N+K)保障
  • 空間複雑度は高いが、速度は速い.
  • は、まずリストを初期化し、カウントを行い、インデックス順に出力、
  • をソートする.
    # 모든 원소의 값이 0보다 크거나 같다고 가정
    array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]
    # 모든 범위를 포함하는 리스트 선언 (모든 값은 0으로 초기화)
    count = [0] * (max(array) + 1)
    
    for i in range(len(array)): # 각 데이터에 해당하는 인덱스의 값 증가
        count[array[i]] += 1
    
    for i in range(len(count)): # 리스트에 기록된 정렬 정보 확인
        for j in range(count[i]):
            print(i, end= ' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력
            
    >>> 0 0 1 1 2 2 3 4 5 5 6 7 8 9 9