web-dev-qa-db-ja.com

リストをインプレースでソートするためのスワップの最小数をどのように計算しますか?

インプレースソートは基本的に、追加のストレージを使用せずに要素を交換することですよね?

リストに必要なスワップの最小数を見つけるにはどうすればよいですか?

A C D Q R Z   E   // input
| | | > > > <<<   // movement
A C D E Q R   Z   // output

スワッピング:

A C D Q R Z E

swap Q with E, ACDERZQ
swap R with Q, ACDEQZR
swap R with Z, ACDEQRZ. done.

3スワップ。

アイテムを左または右にシフトすることは基本的に入れ替えですが、アイテムをラインから外して、その場所を別のものに切り替えるための最適な数が必要です。

6
sova

リストを最終状態がわかっている別の状態に操作する問題を考えてみましょう。

  1. 1よりも大きい各「囲まれたサブグラフ」を見つけます(これについては後で説明します)。
  2. サブグラフの長さの合計を見つけ、サブグラフの数を引きます。
  3. スワップの数に対するあなたの答えがあります。

「囲まれたサブグラフ」は、最初のリストの各項目が最後のリストにもある全体の最小のサブセットです。

したがって、初期状態からインデックス4、5、9でサブグラフを作成し、それらの値が10、20、30の場合、それが「囲まれたサブグラフ」になるためには、最後から値を見つけることができるはずです。インデックス4、5、9で状態を示し、それらの値は10、20、30である必要があります(ただし、この順序である必要はありません)。

このことを考慮:

a b c d f e
    |
    v
b a d f c e

これには明らかに3つのスワップが必要です。 (a <=> b、c <=> d、c <=> f)

上記のアルゴリズムを適用すると、次のようになります。

  1. 3 '囲まれたサブグラフ'、([a、b]、[c、d、f]、[e])
  2. 複数のアイテムを持つ2つのサブグラフ([a、b]、[c、d、f])
  3. これらすべてのサブグラフには5つのアイテムがあります
  4. 5-2 ==答え。

最小限の数のスワップを実行してソートされた順序にしたい場合は少し難しくなりますが、不可能ではありません。

  1. リスト内の各アイテムのソートされた順序インデックスを見つけます。データを移動したくない場合は、n ^ 2回です。
  2. 「囲まれたサブグラフ」を見つけます。
  3. リスト内のアイテムを入れ替えて正しい順序にしますが、同じサブグラフ内のアイテムのみを入れ替えます。

だから、ソートの順序に到達するために最小限の数のスワップを実行することは不可能ではないことがわかると思いますが、ばかげた数の比較が必要なため、その価値はありません。ヒープソートを使用してください。

9
dan_waterworth

単純な選択ソートはどうですか?

  1. 最小値を見つける(A C D Q R Z E)
  2. Min()の場合は交換!=最初の要素
  3. (C D Q R Z E)で繰り返す
  4. スワップの数を数えます。

あなたの例では:

  1. A C Dはすでに使用されているため、スワップは不要です。
  2. Eを配置するために必要な最初のスワップ(その後、配列はA C D E R Z Qになります)
  3. QはR Z Qの最小値であり、再度スワップして配置します(その後、配列はA C D E Q Z Rになります)
  4. RはZ Rの最小値であり、交換して配置します。 (最終的に配列はA C D E Q R Zになります)。

...グラフなしでとてもシンプル:)

4
Vikas

これはどうですか:インデックスiとjで2つの要素を交換するたびに、どこかでタプル(i、j)として記録します。リストがソートされると、抽象的な代数の本を破り、順列、より具体的には転置について読み上げます。順列には正準サイクル分解があり、正準分解を取得したら、そこから転置の最小セットを抽出する方法を考え出すことができます。私は、各サイクルを最小限の数の転置に拡張する貪欲なアルゴリズムを考えています。これを行う方法は1つだけであるはずですが、これが全体として最小限の数の転置を与えるかどうかはわかりません。私の抽象代​​数は以前ほど良くないので、cs理論スタックでこの質問をすることもできます。

0
davidk01

ウィキペディアにリストされているほとんどのアルゴリズムは、使用される定数スペース、最小の反復(比較または実行されるコード)として最適化されています。おそらくスワップ最適化アルゴリズムが存在しますが、私の知識ではありません。

ここで私が頭に浮かぶ簡単な解決策があります。 (最適ではありませんが、十分良い答えです。最適が必要な場合は、ソリューションツリーを列挙する必要がある場合があります)

  1. 誤って配置されたノードを特定し、カウントをMにします(最悪のシナリオ)
  2. 複数のアルゴリズムを実行し、必要なスワップをマークし、スワップ> Mの場合は切り捨てます
  3. 異なるアルゴリズムの最小Mを更新する
  4. 満足するまで4まで繰り返します
0
Zekta Chan