Edit this page | Report an issue |
要素数を $n$ とし、挿入・削除するデータを $x$ とおく。
要素 $x$ を最下段に左詰めで挿入したあと、$x$ の親が自身より小さい数になるまで、$x$ と親の位置を交換していく。ヒープの高さは $\log_2 n$ 以下なので、比較・交換は最大でも $\log_2 n$ 回。よって挿入の計算量は $O(\log n)$。
要素 $x$ を削除したあと、ヒープの最後尾1の要素 $p$ を $x$ の位置に移動させる。
$p$ が2つの子のいずれかよりも大きい場合、小さい方の子と $p$ を入れ替える。この操作を $p$ が2つの子より大きくなるまで繰り返す。
ヒープの高さは $\log_2 n$ 以下なので、比較と入れ替えの回数は最大でも $\log_2 n$ 回となる。よって削除の計算量は $O(\log n)$。
長さ $n$ の配列 $A$ からヒープを構成するとする。各要素を1つずつヒープに挿入していくときの計算量は $O(\log n)$ であるので、ヒープの構成コストは $O(n\log n)$。
長さ $n$ の配列を $A$ とする。$A$ をヒープソートする手順は以下の通り。
Step 1 のヒープの構成コストは $O(n\log n)$、Step 2 の要素の取り出しコストは $O(1)$、Step 3 のヒープの再構成コストは $O(\log n)$ である。
よって、ヒープソート全体の計算量は、
\(\begin{align*}
T(n) &= O(n\log n) + n\cdot\{O(1) + O(\log n)\} \\
&= O(n\log n)
\end{align*}\)
あらかじめ範囲がわかっている整数値については、$O(n)$ のソートアルゴリズムが存在する。
長さ $n$ の配列を $A$ とし、$A$ の要素は $m$ 個の整数値しか取らないと分かっているとする。
このとき、$A$ にバケットソートを適用する手順は次のとおり。
i
に対応する B[i]
の値を1ずつ増やしていく。B[i]
個ずつ i
を並べてできた配列が $A$ のソート済み配列である。計算量は Step 2 が $O(n)$、Step 3 が $O(m)$ であるが、後者は $n$ に依存しない定数である。よって、バケットソートの時間計算量は $O(n)$。
また、空間計算量は $O(m)$ であるが、$m$ が大きい場合は大規模なメモリが必要である。
時間計算量 $O(n)$、空間計算量 $O(90)=O(1)$
整数の桁ごとにバケットソートを適用することで、使用メモリを抑えたアルゴリズムを基数ソートと呼ぶ。
配列 $A$ の要素の整数が、$0,1,2,\cdots,10^k-1$ であるとする。このとき基数ソートの手順は次の通り。
個々のバケットソートの計算量は $O(n)$ で、これを $k-1$ 回繰り返すので、基数ソートの計算量は $O(kn)$。よって、$k$ を定数とみなせば $O(n)$ である。
また、バケットソートではバケツの数は10で良い。しかし、最悪の場合、1つのバケツに $n$ 個のデータ全てが入ってしまう。これを表現するためには、9つのバケツ同士の境目と、$n$ 個の数字を格納するスペースがあれば良い。よって、空間計算量は $O(n+9)=O(n)$2。
時間計算量 $O(10n) = O(n)$、空間計算量 $O(99)=O(1)$
設問1 (a)-(c):各8点
設問2,3:各13点
(50点満点)
コメントはGithubレポジトリにIssueとして投稿されます。