アルゴリズムリフレッシャー。ヒープソートが分類アルゴリズムであるのはなぜですか?


15

ヒープソートがインプレースソートアルゴリズムと見なされる理由がわかりません。

つまり、並べ替えられる配列の要素(つまりヒープ)が追加され追加のデータ構造を使用して、最小値の抽出と並べ替えプロセスを支援します。

ここでインプレースの定義を誤解しているのではないでしょうか?

しかし、たとえば挿入ソートは、インプレースアルゴリズムである、つまり要素に余分なメモリが必要ないことは明らかです。

それで、なぜそれはインプレースと見なされますか?

回答:


12

つまり、ソートされる配列の要素(ヒープ)が追加された追加のデータ構造を使用して、最小値の抽出とソートプロセスを支援します。

いいえ。配列は、O(1)を超える余分なメモリを使用せずに、ヒープ制約に適合するように変換されます。(実際に必要なのは、スワップの目的で配列の1つの要素を保持するのに十分な追加メモリと、ブール値または2つ、ループ変数または2つだけです)。

技術的には、ヒープソートは通常、別個のヒープを使用するものとして説明されるかもしれませんが、その場で実装することは完全に可能です。


3
別のヒープ(コード内)を持つ "ヒープソート"が表示されると予想される唯一の場所は、Haskellのような関数型言語です。同じ理由で、通常の関数型 "クイックソート"それらのリストはたくさんあり、インプレースソートはステートフルです-データを含む配列/何でも状態を変更します。怖い引用です。なぜなら、場違いのクイックソートがクイックソートである、または場違いのヒープソートがヒープソートであるとは本当に受け入れないからです。少なくとも、場所。
Steve314

1
@ Steve314、「ヒープに入れてから、一度に1つずつ要素を引き出して配列に入れる」という効果を説明する教材を見たことがあると思います。しかし、CLRを確認しただけで、インプレースバージョンを示していると報告できます。
ピーターテイラー

2
@PeterTaylor:はい、私がレビューしていた本(Skiena)は、余分なヒープを構築してヒープソートを提示しました。
user10326

4

配列を使用してツリーのレイアウトを指定できるという基本的な理解が欠けている場合があります。

バイナリツリーがあり、内部ノードが配列のインデックスiにあるとします。次に、そのノードの親と子の配列インデックスは次の方法で見つけることができます。

Parent(i) = floor(i/2)
Left child(i) = 2i
Right child(i) = 2i + 1

見る:

http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/Sorting/heapSort.htm

ヒープは完全に配列内に保持および編成できるため、入力配列内で要素を移動することにより、ヒープソートをその場で実行できます。実際、ヒープは元の入力配列を使用して構築および操作されます。


:私はこれについて知っています。問題は、私が読んでいる本が別のヒープを使用してヒープソートを提示したことのようです。このプレゼンテーションはアルゴリズムを理解しやすくすることを理解していないと思いましたそのように提示された)
-user10326

Cormen等の著書「Introduction to Algorithms」を購入することを強くお勧めします。アルゴリズム関連のすべての質問に明確に回答します。コンピューター科学者またはソフトウェアエンジニアとしてのキャリアを真剣に考えているなら、この本が必要です。
stackoverflowuser2010

1

あなたが言うように、ヒープを構築するために特別な構造が本当に必要な場合、ヒープソートは実際にはインプレースソートアルゴリズムではありません。

ただし、そうではありません。並べ替えるのとまったく同じ配列にヒープを構築し、その後ヒープソートアルゴリズムを適用して、その場で並べ替えることができます。


基本的に、IIRC O(n)時間のヒープのルールに準拠するように、配列内のデータを並べ替えるために使用される「ヒープ化」アルゴリズムがあります。Programmers.stackexchange.com/questions/116904/…の擬似コードを参照してください。その後は、ほとんどの場合、ヒープのルート抽出を繰り返し行い、配列のどの程度が「ヒープ」であり、最終結果としてどれだけソートされているかを追跡します。
Steve314

0

コンピューターサイエンスでは、インプレースアルゴリズム(またはラテン語のin situ)は、少量の一定量の追加ストレージスペースを持つデータ構造を使用して入力を変換するアルゴリズムです。通常、入力は、アルゴリズムの実行時に出力によって上書きされます。インプレースでないアルゴリズムは、インプレースまたはアウトオブプレースと呼ばれることもあります。

ウィキペディア-インプレースアルゴリズム


では、なぜmergesortは非定型アルゴリズムと見なされるのでしょうか?
user10326

3
これは便利な返信ではありません。ヒープソートとは関係なく、質問に答えません。
stackoverflowuser2010

もちろん、ヒープソートと関係があります。定義から明らかなように、ヒープソートはインプレースソートアルゴリズムです。実際、それはヒープソートページからリンクされていました。
ラインヘンリッヒ

0

スペース要件が無視できる(ビット単位の操作を使用してアイテムをスワップする場合は一定またはまったくない)ため、適切に考慮されます。たとえば、MergeSortは、検索セットの各反復で入力セットが変更されないため、適切ではありません。

インプレースアルゴリズムとアウトオブプレースアルゴリズムの違いを説明する最良の方法は、おそらく、それをインプレースで実行する次のC / C ++文字列反転コードを調べることです(K&Rから)。

void reverse(char s[])
{
      int c, i, j;

      for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
      }
}

たとえば、入力文字列を最後から読み取り、文字を別のバッファに配置する場合、アウトオブプレースの文字列反転アルゴリズムになります。


1
Mergesortはいらいらしている- あなたがインプレース戦略を持っていることを間違って自分自身に納得させるのは簡単です。通常、小さな配列でのみ機能します。ただし、マージソートアルゴリズムのインプレースバリアントを誰かが解決した論文を一度ダウンロードしたと思います。もう一度見つけることができるかどうかを確認します。
Steve314
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.