2021.11.30追記: 記事壊れました.

はじめに

以下の本を読みながら、アルゴリズムの勉強を始めてます.

<div class='amazlink-box' style='text-align:left;padding-bottom:20px;font-size:small;/zoom: 1;overflow: hidden;'>
  <div class='amazlink-list' style='clear: both;'>
    <div class='amazlink-image' style='float:left;margin:0px 12px 1px 0px;'>
      <a href='https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E6%94%BB%E7%95%A5%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%E6%B8%A1%E9%83%A8-%E6%9C%89%E9%9A%86/dp/4839952957%3FSubscriptionId%3DAKIAJDINZW45GEGLXQQQ%26tag%3Dsleephacker-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4839952957https://ecx.images-amazon.com/images/I/51oWwpzibRL._SL160_.jpg' style='border: none;' /></a>
    </div>
    
    <div class='amazlink-info' style='height:160; margin-bottom: 10px'>
      <div class='amazlink-name' style='margin-bottom:10px;line-height:120%'>
        <a href='https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E6%94%BB%E7%95%A5%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%E6%B8%A1%E9%83%A8-%E6%9C%89%E9%9A%86/dp/4839952957%3FSubscriptionId%3DAKIAJDINZW45GEGLXQQQ%26tag%3Dsleephacker-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4839952957' rel='nofollow' target='_blank'>プログラミングコンテスト攻略のためのアルゴリズムとデータ構造</a>
      </div>
      
      <div class='amazlink-powered' style='font-size:80%;margin-top:5px;line-height:120%'>
        posted with <a href='https://amazlink.keizoku.com/' title='アマゾンアフィリエイトリンク作成ツール' target='_blank'>amazlink</a> at 15.11.28
      </div>
      
      <div class='amazlink-detail'>
        渡部 有隆
      </div>
      
      <div class='amazlink-sub-info' style='float: left;'>
        <div class='amazlink-link' style='margin-top: 5px'>
          <img src='https://amazlink.fuyu.gs/icon_amazon.png' width='18' /><a href='https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E6%94%BB%E7%95%A5%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%E6%B8%A1%E9%83%A8-%E6%9C%89%E9%9A%86/dp/4839952957%3FSubscriptionId%3DAKIAJDINZW45GEGLXQQQ%26tag%3Dsleephacker-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4839952957' 
        </div>
      </div>
    </div>
  </div>
</div>

<ul class="org-ul">
  <li>
    <a href="https://judge.u-aizu.ac.jp/onlinejudge/user.jsp?id=tsu_nera">https://judge.u-aizu.ac.jp/onlinejudge/user.jsp?id=tsu_nera</a>
  </li>
</ul>

<p>
  書籍では、C, C++の実装例が載っている.自分は、Pythonで実装してみた. 紹介するのは以下.
</p>

<ul class="org-ul">
  <li>
    挿入ソート
  </li>
  <li>
    バブルソート
  </li>
  <li>
    選択ソート
  </li>
  <li>
    マージソート
  </li>
  <li>
    シェルソート
  </li>
  <li>
    クイックソート
  </li>
</ul>

挿入ソート(Insertion Sort)

挿入ソート(インサーションソート)は、ソートのアルゴリズムの一つ。整列 してある配列に追加要素を適切な場所に挿入すること。平均計算時間・最悪計 算時間がともにO(n2)と遅いが、アルゴリズムが単純で実装が容易なため、し ばしば用いられる。安定な内部ソート。基本挿入法ともいう。in-placeアルゴ リズムであり、オンラインアルゴリズムである。

<ul class="org-ul">
  <li>
    <a href="https://ja.wikipedia.org/wiki/%E6%8C%BF%E5%85%A5%E3%82%BD%E3%83%BC%E3%83%88">挿入ソート - Wikipedia</a>
  </li>
</ul>

ALDS1_1_A

<div class="outline-text-3" id="text-orgheadline3">
  <p>
    サンプル問題(AOJ): <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_A&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_A&lang=jp</a>
  </p>
  
  <p>
    [sourcecode language="python" title="" ] N = int(input()) A = list(map(int, input().split()))
  </p>
  
  <p>
    def insertion_sort(A, N): for i in range(1, N): v = A[i] j = i - 1 while j >= 0 and A[j] > v: # vより大きければ右へずらす A[j+1] = A[j] j -= 1 A[j+1] = v print(*A)
  </p>
  
  <p>
    print(*A) insertion_sort(A, N) [/sourcecode]
  </p>
</div>

バブルソート(Bubble Sort)

バブルソート (bubble sort) は、ソートのアルゴリズムの一つ。隣り合う要 素の大小を比較しながら整列させること。最悪計算時間がO(n2)と遅いが、ア ルゴリズムが単純で実装が容易なため、また並列処理との親和性が高いことか ら、しばしば用いられる。安定な内部ソート。基本交換法、隣接交換法ともい う。(単に交換法と言う場合もある)

<ul class="org-ul">
  <li>
    <a href="https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%96%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88">バブルソート - Wikipedia</a>
  </li>
</ul>

ALDS1_2_A

<div class="outline-text-3" id="text-orgheadline5">
  <p>
    サンプル問題(AOJ) <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A&lang=jp</a>
  </p>
  
  <p>
    [sourcecode language="python" title="" ] N = int(input()) A = list(map(int, input().split()))
  </p>
  
  <p>
    def bubble_sort(A, N): cnt = 0 flag = True while(flag): flag = False for i in range(N-1, 0, -1): if(A[i-1] > A[i]): A[i-1], A[i] = A[i], A[i-1] cnt += 1 flag = True
  </p>
  
  <p>
    print(" ".join(list(map(str, A)))) print(cnt)
  </p>
  
  <p>
    bubble_sort(A, N) [/sourcecode]
  </p>
</div>

選択ソート(Selection Sort)

選択ソート(英: selection sort)は、ソートのアルゴリズムの一つ。配列さ れた要素から、最大値やまたは最小値を探索し配列最後の要素と入れ替えをお こなうこと。最悪計算時間がO(n2)と遅いが、 アルゴリズムが単純で実装が容易なため、しばしば用いられる。内部ソート。 後述するように、安定ソートではない。

<ul class="org-ul">
  <li>
    <a href="https://ja.wikipedia.org/wiki/%E9%81%B8%E6%8A%9E%E3%82%BD%E3%83%BC%E3%83%88">選択ソート - Wikipedia</a>
  </li>
</ul>

ALDS1_2_B

<div class="outline-text-3" id="text-orgheadline7">
  <p>
    サンプル問題(AOJ) <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B&lang=jp</a>
  </p>
  
  <p>
    ↓のコード、どうしてもAOJ のテストケースを通せなかった。 どこかバグってるのだろうか??
  </p>
  
  <p>
    [sourcecode language="python" title="" ] def selection_sort(A, N): count = 0 for i in range(0, N): minj = i for j in range(i, N): if(A[minj] > A[j]): minj = j if(minj != i): count += 1 A[minj], A[i] = A[i], A[minj]
  </p>
  
  <p>
    print(" ".join(map(str, A))) print(count)
  </p>
  
  <p>
    N = int(input()) A = list(map(int, input().split())) selection_sort(A, N) [/sourcecode]
  </p>
</div>

シェルソート(Shell Sort)

基本的な部分は、挿入ソートと同じである。挿入ソートは「ほとんど整列され たデータに対しては高速」という特長があるものの、「隣り合った要素同士し か交換しない」ため、あまり整列されていないデータに対しては低速であった。

  <p>
    そのため、適当な間隔をあけた飛び飛びのデータ列に対してあらかじめソート しておき、挿入ソートを適用すれば高速になると考えられる。この考え方を適 用したのがシェルソートである。
  </p>
</blockquote>

<ul class="org-ul">
  <li>
    <a href="https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88">シェルソート - Wikipedia</a>
  </li>
</ul>

ALDS1_2_D

<div class="outline-text-3" id="text-orgheadline9">
  <p>
    サンプル問題(AOJ)
  </p>
  
  <ul class="org-ul">
    <li>
      <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_D&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_D&lang=jp</a>
    </li>
  </ul>
  
  <p>
    コード省略。解けない..
  </p>
</div>

マージソート(Merge Sort)

分割統治法によるソート.

<blockquote>
  <p>
    マージソートは、ソートのアルゴリズムで、既に整列してある複数個の列を1 個の列にマージする際に、小さいものから先に新しい列に並べれば、新しい列 も整列されている、というボトムアップの分割統治法による。大きい列を多数 の列に分割し、そのそれぞれをマージする作業は並列化できる。
  </p>
  
  <p>
    n個のデータを含む配列をソートする場合、最悪計算量O(n log n)である。分 割と統合の実装にもよるが、一般に安定なソートを実装できる。インプレース なソートも提案されているが、通常O(n)の外部記憶を必要とする。
  </p>
  
  <p>
    (ナイーブな)クイックソートと比べると、最悪計算量は少ない 。ランダムなデータでは通常、クイックソートのほうが速い。
  </p>
</blockquote>

<ul class="org-ul">
  <li>
    <a href="https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88">マージソート - Wikipedia</a>
  </li>
</ul>

ALDS1_5_B

<div class="outline-text-3" id="text-orgheadline11">
  <p>
    サンプル問題(AOJ) <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_B&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_B&lang=jp</a>
  </p>
  
  <p>
    [sourcecode language="python" title="" ] def merge(A, left, mid, right): global count L = A[left:mid] + [1000000001] R = A[mid:right] + [1000000001] i = j = 0 for k in range(left, right): if L[i] <= R[j]: A[k] = L[i] i += 1 else: A[k] = R[j] j += 1 count += right - left def merge_sort(A, left, right): if left + 1 < right: mid = (left + right) // 2 merge_sort(A, left, mid) merge_sort(A, mid, right) merge(A, left, mid, right) N = int(input()) A = list(map(int, input().split())) count = 0 merge_sort(A, 0, N) print(*A) print(count) [/sourcecode] </div> </div> </div> 
    
    <div id="outline-container-orgheadline12" class="outline-2">
      <h2 id="orgheadline12">
        クイックソート(Quick Sort)
      </h2>
      
      <div class="outline-text-2" id="text-orgheadline12">
        <blockquote>
          <p>
            クイックソート (quicksort) は、1960年にアントニー・ホーアが開発した ソートのアルゴリズム。分割統治法の一種。
          </p>
          
          <p>
            最良計算量および平均計算量はO( nlog n )である。他のソート法と比べて、 一般的に最も高速だといわれているが対象のデータの並びやデータの数によっ ては必ずしも速いわけではなく、最悪の計算量はO( n^2)である。また数々 の変種がある。 安定ソートではない。
          </p>
        </blockquote>
        
        <ul class="org-ul">
          <li>
            <a href="https://ja.wikipedia.org/wiki/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%BD%E3%83%BC%E3%83%88">クイックソート - Wikipedia</a>
          </li>
        </ul>
      </div>
      
      <div id="outline-container-orgheadline13" class="outline-3">
        <h3 id="orgheadline13">
          ALDS1_6_B, ALDS1_6_C
        </h3>
        
        <div class="outline-text-3" id="text-orgheadline13">
          <p>
            サンプル問題(AOJ) <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_6_B&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_6_B&lang=jp</a> <a href="https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_6_C&lang=jp">https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_6_C&lang=jp</a>
          </p>
          
          <p>
            [sourcecode language="python" title="" ] def partition(a, p, r): x = a[r][1] i = p - 1 for j in range(p, r): if a[j][1] <= x: i = i + 1 a[i], a[j] = a[j], a[i] a[i + 1], a[r] = a[r], a[i + 1] return i + 1 def quicksort(a, p, r): if p < r: q = partition(a, p, r) quicksort(a, p, q - 1) quicksort(a, q + 1, r) import sys n = int(input()) a = [] for i in range(n): suit, num = sys.stdin.readline().split() a += [[suit, int(num), i]] quicksort(a, 0, len(a) - 1) [/sourcecode] </div> </div> </div> 
            
            <div id="outline-container-orgheadline14" class="outline-2">
              <h2 id="orgheadline14">
                Python 標準ライブラリ
              </h2>
              
              <div class="outline-text-2" id="text-orgheadline14">
                <p>
                  リストオブジェクトに対する操作として、 sort()や, reverse()メソッドが用意されている.
                </p>
                
                <p>
                  [sourcecode language="python" title="" ] listobj.sort() listobj.reverce() [/sourcecode]
                </p>
                
                <ul class="org-ul">
                  <li>
                    <a href="https://qiita.com/fantm21/items/6df776d99356ef6d14d4">【Python】ソート - Qiita</a>
                  </li>
                  <li>
                    <a href="https://www.pythonweb.jp/tutorial/list/index11.html">要素のソート(sortメソッド, reverseメソッド) - リスト - Python入門</a>
                  </li>
                </ul>
              </div>
            </div>
            
            <div id="outline-container-orgheadline15" class="outline-2">
              <h2 id="orgheadline15">
                Special Thanks
              </h2>
              
              <div class="outline-text-2" id="text-orgheadline15">
                <ul class="org-ul">
                  <li>
                    <p>
                      <a href="https://gigazine.net/news/20140501-sorting/">数あるソートアルゴリズムをビジュアル化し堪能できるサービス「SORTING」 - GIGAZINE</a>
                    </p>
                    
                    <p>
                      ソーティングアルゴリズムを可視化した動画がオモシロイ.
                    </p>
                  </li>
                </ul>
                
                <p>
                  <iframe width="560" height="315" src="https://www.youtube.com/embed/kPRA0W1kECg" frameborder="0" allowfullscreen></iframe>
                </p>
                
                <ul class="org-ul">
                  <li>
                    <a href="https://kojikoji75.hatenablog.com/entry/2013/09/21/115937">プログラムで簡単理解! 7つの超重要な整列アルゴリズム(ソートアルゴリズム)まとめ - TechNote</a>
                  </li>
                  <li>
                    <p>
                      <a href="https://qiita.com/hiso/items/5c36f50c7de61fe870a2">基本的なソートアルゴリズムまとめ+α。C言語での実装例 - Qiita</a>
                    </p>
                    
                    <p style="font-size:32px">
                      以上、Happy Hacking!!
                    </p>
                  </li>
                </ul>
              </div>
            </div>