tl;dr: 双方向リンク リストに効率的にクイックソートを実装することは可能ですか? それについて考える前の私の理解は、いや、そうではありませんでした。
先日、基本的なソート アルゴリズムのイテレータ要件について検討する機会がありました。基本的な O(N²) のものはかなり簡単です。
- バブル ソート - 2 つの順方向イテレータが適切に機能し、一方が他方をドラッグします。
- 挿入ソート - 2 つの双方向反復子で十分です。1 つは順不同の要素用、もう 1 つは挿入ポイント用です。
- 選択ソート - 少しトリッキーですが、前方イテレータがそのトリックを実行できます。
クイックソート
std::sort の introsort_loop (gnu 標準ライブラリ/ hp(1994) / Silicon Graphics(1996) など) では、random_access である必要があります。
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Size __depth_limit, _Compare __comp)
私が期待するようになったように。
よく調べてみると、クイックソートにこれを必要とする本当の理由が見つかりません。random_access_iterators を明示的に必要とする唯一のものstd::__median
は、中間要素の計算を必要とする呼び出しです。通常のバニラのクイックソートは中央値を計算しません。
パーティショニングはチェックで構成されています
if (!(__first < __last))
return __first;
双方向の有用なチェックではありません。ただし、これを前のパーティショニング トラベル (左から右/右から左) のチェックに置き換えることができるはずです。単純な条件は次のとおりです。
if ( __first == __last ) this_partitioning_is_done = true;
双方向イテレータのみを使用してかなり効率的にクイックソートを実装することは可能ですか? 再帰的な深さは引き続き保護できます。
注意。私はまだ実際の実装を試みていません。