どーも、情報系大学生のゆうき(@engieerblog_Yu)です。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/e5b2bb3a54f4aa0de9bce2dc481e8378-1024x236.jpg)
今回はこのような配列を昇順(小さい順)に並び替えていくことを考えましょう。
みなさんはどのように整列しようと考えるでしょうか?
整列の方法はいろいろありますが、計算量の観点でどのような整列アルゴリズムを選ぶかが大切になってきます。
今回はその中のヒープソートをまとめていきたいと思います。
過去の記事も併せてどうぞ。
まずはヒープソートに使われる二分ヒープについてです。
二分ヒープについて
二分ヒープは以下の条件を満たします。
親ノードよりも子ノードの方が値が大きい
広義の完全二分木になっている(全ての葉が左詰めになっている)
(親ノードよりも子ノードが小さいものとして二分ヒープを構成している場合もあります。)
二分ヒープは主に、挿入と最小値の削除を効率的に実行することができます。
詳しくはこちらの記事で解説しています。
ヒープソートは二つのフェーズに分かれます。
ヒープの初期化
最大値の削除
それでは、先ほどの配列をヒープソートを使って昇順にソートしていきたいと思います。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/e5b2bb3a54f4aa0de9bce2dc481e8378-1-1024x236.jpg)
ヒープの初期化(前半フェーズ)
先ほどの配列をヒープで表すと以下のようになります。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/9c4977b0b65c2f3449f254021ec078b6-1024x795.jpg)
配列の後ろにある要素から、ヒープの初期化を行なっていきます。
ヒープの初期化とは親が子よりも大きい値を持つヒープを構成することです。
今回は9、4、1の順番で値を交換していくことになります。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/a471a6d9a5f088f74e30b8477b1dfd56-1024x569.jpg)
9と3は9の方が大きいのでそのままです。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/c0f0078b2547be9c6797d84c58044333-1024x499.jpg)
次に4を見ると、4と2と6で6が一番大きいので4と6を交換します。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/185107182b10270282656745046b96ff-1024x485.jpg)
最後に1を見ると1と6と9の中で9が一番大きいので1と9を交換します。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/ccd7744073c86b897c1f5a1e2825f48d-1024x526.jpg)
1と9を交換した時に3の方が1より大きいので交換します。(忘れがちです)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/38f4919d69f6fc2be44db6cd99c7e48c-1024x807.jpg)
ヒープの条件を満たすことができていることがわかります。
ヒープの初期化の計算量はO(n)となります。
最大値の削除(後半フェーズ)
次に最大値を削除していきます。
最大値の削除では以下のことを行います。
1.根の値を配列の一番後ろに格納する
2.ヒープの一番後ろの要素を根に移動する
3.ヒープ条件を満たすように、ヒープを再構築する
4.ヒープの要素がなくなるまで繰り返す
まず根にある9を配列の一番後ろに移動します。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/cb89ab6350e8368e6ca6d4f6444facf4-1024x499.jpg)
ヒープの一番後ろにある1が根に交換されます。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/bdc86dbd67758ebdb6532ba5e59b7864-1024x646.jpg)
ヒープの条件が満たされていることが確認できたら、次は6を配列に移動します。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/7bcbff54a7a264be6deeda7bad468b05-1024x470.jpg)
ヒープの一番後ろにある要素を根と交換して、同じ操作を繰り返していきます。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/a5ca829d373c2d3bd007eebc5780583a-1024x896.jpg)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/c4ea3937c68845db9f0527529a1bea12-1024x511.jpg)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/dafa6196dbc7137bd7749b661f117ce7-1024x783.jpg)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/7162ace2b3894710774bb29f1992ef75-1024x379.jpg)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/ba28fe3ec62cb4c8ebdbbfc1b0d80e99-1024x841.jpg)
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/dba2753bcab4d495a531c817cb26e488-1024x370.jpg)
最後に1が残るのでA[0]に移動してあげれば昇順にソートすることができます。
![](https://prog-you.com/syohyou/wp-content/uploads/2022/08/0b1e9b8367b57a07007130038f2d2a2c-1024x372.jpg)
最大値の削除の計算量はO(nlogn)となります。
またそれにより全体の計算量はO(nlogn)になります。
ヒープソートの計算量はO(n)+O(nlogn)=O(nlogn)となる
まとめ
ヒープソートはヒープの初期化と最大値の削除により行われる
計算量はO(nlogn)となる
アルゴリズムの勉強におすすめの書籍です。
![ゆうき](https://prog-you.com/syohyou/wp-content/uploads/2022/04/d160a53f71104dc4e5ed3c300ba3ba79-1.png)
整列アルゴリズムの計算量はO(nlogn)よりも小さくことはできないと証明されているので、極めて優秀なアルゴリズムと言うことができます。
![ねこすけ](https://prog-you.com/syohyou/wp-content/uploads/2022/04/fcedeb3e47d759777985cdd471841cd1-1.png)
いろんな投稿があるにゃ。
コメント