平均時間計算量はまだであるというあなたの仮定に同意しますO(n log n)
。私は専門家ではなく、100%確信していますが、これらは私の考えです。
これは、インプレースクイックソートの擬似コードです:( l =1およびr=配列の長さでクイックソートを呼び出します)
Quicksort(l,r)
--------------
IF r-l>=1 THEN
choose pivot element x of {x_l,x_l+1,...,x_r-1,x_r}
order the array-segment x_l,...x_r in such a way that
all elements < x are on the left side of x // line 6
all elements > x are on the right side of x // line 7
let m be the position of x in the 'sorted' array (as said in the two lines above)
Quicksort(l,m-1);
Quicksort(m+1,r)
FI
次に、平均時間計算量分析は、このアルゴリズムの主要な操作として6行目と7行目の「<」比較を選択することによって推論し、最終的に平均時間計算量はO(n log n)であるという結論に達します。「配列セグメントx_l、... x_rを...のように並べ替える」という行のコストは考慮されていないため(境界を見つけたい場合は、時間計算量分析では主要な操作のみが重要です)、私は思います「それを分割するときにリストの2つのパスを実行する必要があるため」は問題ではありません。また、Haskellバージョンはこのステップで約2倍の時間がかかるためです。同じことが付録操作にも当てはまり、これが漸近コストに何も追加しないことに同意します。
アペンドとパーティションは、非効率的であっても、線形時間計算量を持っているためです。
便宜上、これにより時間計算量のコストに「n」が加算され、「O(n log n + n)」になると仮定します。そのnlogn> nには自然数oが存在し、oより大きいすべての自然数が当てはまるため、n log n+nを上から2nlog nまで、下からnlognまで推定できます。 n log n + n = O(n log n)。
さらに、ピボットとして最初の要素を選択することは最良の選択ではありません。
平均的なケース分析では、配列内の要素が均一に分布していると想定しているため、ここではピボット要素の選択は重要ではないと思います。配列内のどの場所から選択する必要があるかわからないため、ピボット要素(リストのどの場所から取得するかとは関係なく)がi番目に小さい要素であるこれらすべてのケースを考慮する必要があります。リストの、i = 1...rの場合。