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>