Ch 03. 分割征服アルゴリズム(1)

9199 ワード

分割征服アルゴリズムとは?


コンセプト

  • 分割を適用する入力->同じアルゴリズム->計算->集約
  • 一部問題:分割入力に関する問題
  • 部分解:部分問題の解
  • プロセス

  • 分割
  • 征服(分割可能状態であれば「分割」に戻る)
  • 結合
    入力サイズnの場合、총 분할 횟수k=log n
  • 種類

  • 部分問題数a、部分問題サイズbによる分類
  • 1.a個に分割し、1/bに減少
  • a=b=2:並べ替えて、一番近い二重接点を探す
  • a=3,b=2:大整数の積
  • a=4,b=2:大整数の積
  • a=7,b=2:ライセンスのマトリックス乗算アルゴリズム
  • 2.a=2,b=一定数X減少
  • クイックソート
  • 3.a=2(どちらかを無視)、1/2に減少
  • バイナリ探索
  • 4.a=2(いずれかを無視)、b=一定X減少
  • 選択問題アルゴリズム
  • 5.b=1.2個
  • 挿入ソート、フィボナッチ数
  • 連結ソート


    コンセプト

  • 部分問題数:2個
  • 局所問題サイズ:1/2減少
  • に道を教える

  • 分割:n個入力->n/2部を1個まで平らにする
  • 征服:部分配列順
  • 結合:部分配列を一体化

  • インプリメンテーション

  • 分割
  • 配列要素数が2個を超えると(1個まで)半分に分けられる.
  • 連結ソート
  • 配管の前に要素を1つずつ抽出して比較し、新しい配管にまとめた感じで並べた部分を統合する.
  • Pseudo-code
    MergeSort(A, p, q): #배열 A, 첫 인덱스 p, 끝 인덱스 q
        if p < q: 		#배열 내 원소가 2개 이상일 때
            k = (p + q) // 2	#절반 위치 인덱스(몫만 취함)
            MergeSort(A, p, k)     #앞부분 순환 호출
            MergeSort(A, k + 1, q) # 뒷부분 순환 호출
            Merge(A, p, q)		#부분 배열 합병 정렬  
  • 時間の複雑さ

  • 配列サイズn、分割ツリーを飽和バイナリツリーと見なす場合、
    分割時間の複雑さ:O(1)
    連結回数:logn
    レベル別比較ソート数:n
    したがって,集計ソート時間の複雑さ:O(nlogn)
  • くうかんふくざつさ

  • 併合結果を保存するための一時的な配列が必要:O(n)
  • 特性/利点

  • 安定順位:順序が変わらない
  • 接続リスト並べ替え時有効性
  • 短所

  • O(n)の空間複雑度
  • 適用

  • 外部ソート
  • 接続リスト並べ替え時
  • クイックソート


    コンセプト

  • 部分問題数:2個
  • 局所問題の大きさ:不規則(一定X)
  • に道を教える

  • 軸心確定
  • 軸心未満の数字は左に分割、軸心より大きい数字は右に分割
  • 左/右(一部問題)それぞれ同一プロセス再帰位
  • インプリメンテーション



    1.アレイに複数の要素がある場合、
    1-1. ピボットに沿って配列されたA[左]からA[右]を選択
    1-2. SWAP(A[left],ピボットに沿って);
    1-3. 軸より小さい数値を左に移動し、軸より大きい数値を右に移動します.
    2.軸心より1回循環するプロセス
    3.ピボットより大きいグループ1サイクルプロセス
  • Python
    def quick_sort(arr, start, end):
        if start >= end: return 
        pivot = arr[start] # 피벗은 첫번째 원소
        l, r = start + 1, end
    
        while l <= r:
            while l <= end and arr[l] <= arr[pivot]:
                l += 1
            while r > start and arr[r] >= arr[pivot]:
                r -= 1
            if l > r: 
                arr[r], arr[pivot] = arr[pivot], arr[r]
            else: 
                arr[r], arr[l] = arr[l], arr[r]
        quick_sort(arr, start, r - 1)
        quick_sort(arr, r + 1, end)
    
    A = [5, 3, 8, 4, 9, 1, 6, 2, 7, 10]
    print(quick_sort(A, 0, len(A)))
  • 時間の複雑さ

  • 最悪:O(n^2)軸心최소/최대数字
  • 最適:O(nlog n)-半分に分割した場合(=集計ソート)
  • 平均:O(nlog n)
  • ピボットの選択方法


    クイックソートのパフォーマンスは軸の左右に依存します!
  • ランダム選定
  • 税の中値
    pivot = median{K[l], K[(l+r)/2], K[r]}
  • パフォーマンスの向上

  • 入力が非常に大きい場合は、挿入ソートも併用可能
  • 一部問題の大きさが一定数以下:挿入ソートを使用する
  • 適用/利点

  • 入力サイズが大きいと性能が良い
  • 平均性能が良いソートアルゴリズム
  • 接尾辞配列などの遺伝子を探すための領域
  • +時間複雑度:マージソートVSクイックソート