2016-07-17 6 views
0

たとえば、マージソートでのパフォーマンスを改善するにはどうすればよいですか?マージソート2のマージステップでは、サイズn/2のより小さいリストがサイズnのリストに結合される。これが再帰的に起こっているので、次のティエム・マージが2つの配列をマージするために呼び出されます。これらのリストはサイズnを持ち、新しいリストは2nのサイズを持ちます。エリクシールリストでは不変ですが、初期リストの値、つまりソートしようとしているリストの値を変更することはできません。代わりに、マージの各ステップで新しいリストを作成します。これをどのように改善できますか? 1つはetsを使うだろうか?リスト使用時のエリクサーでのパフォーマンスの向上

+1

新しいリストの作成を避けることはできますが、新しい要素をリストに追加することは、リストに追加するときとは違って古いリストをコピーしないので安価ですこのアルゴリズムで活用されています。 – JustMichael

+0

@JustMichael ++演算子を使用していました。これは、リストを反復しなければならないことを意味し、マージを行うたびにO(n)です。アイテムをリストの先頭に接頭し、必要に応じてリストを逆にする方がよいでしょう。 – sashang

+0

はい、正確には、逆は高度に最適化されているので、このようにする方がよい – JustMichael

答えて

2

エリクサーには、このようなパフォーマンスの問題が多く解決されています。たとえば、mergesortでのマージでこの問題が発生した場合、事前に配列されている配列:lists.mergeが返され、ソートされた配列が1つ返されます。完全なマージソートは、次のようになります。私はエリクシールは右、ソートされた多くのものを持って書いた

defmodule Sort do 
    def merge_sort(input) when length(input) <= 1 do 
    input 
    end 

    def merge_sort(input) do 
    splitting_point = length(input) |> div(2) 
    { left, right } = Enum.split(input, splitting_point) 
    :lists.merge(merge_sort(left), merge_sort(right)) 
    end 
end 

? mergesortも例外ではありません。フードの下でmergesortを使用するEnum.sortを使用して、それを1日と呼びます。

関連する問題