I.背景
就寝時、突然、その後、クイックソートを書い実現のクイックソートの変形を考える、あなたの手を練習するための2行のコードを書きたかった、テスト結果は、理論的には非常に奇妙です、何の問題状況は、デバッグマクロな原因は以下のように、長い時間のために発見されませんでしたレッスンを記録しました。
第二に、クイックソートは、達成するためにバリアント
原理:
| _ | | _ | | _________________________________________ |
L Rソートされていません
-------------------------------------------------- -------------------------------------------------- -----------------
1、センチネル添字低い、すなわち、最初の要素を取っ;そしてR Lは、初期状態を設定するには、L組の値を格納するために使用される、空であるR値のセットを格納するためのピボットよりも大きい、以下ピボットよりも長いです。
ピボット=ベクトル<T>&VEC [低]。MI =低いです。
MI↓
| - |
| _ | | _ | | _________________________________________ |
L Rソートされていません
図2に示すように、トラバースの初期設定、要素の現在のインデックスが任意の操作を行うことなく、ピボットイテレータに添加するよりも、それが大きい発見された場合、効果はRの要素を移動させると等価です
IDX
| _ | | __ | | ________________________________________ |
L Rソートされていません
図3に示すように、見つかった値は以下の要素の現在のインデックスは非常に現在の要素と集合Rスイッチングの最初の要素こと、効率を向上させるために放電電流値集合Lにピボットに必要な、その後イテレータを追加してより長い場合、新しいLに対応する効果素子全体的なシフトの後、R元素を増加させます。
私の
↓IDX
| __ | | __ | | _______________________________________ |
L Rソートされていません
図4に示すように、トラバースされてソートされていない現在のシーケンスが空になり、LおよびRは、ピボット要素セットより全て小さい/大きい方を含むであろう。
私の
↓
| ___________________ | | _________________________ |
L R
図5は、最終的に、すなわち、ピボット要素と呼ばれるが、MIを交換するであろう最初の要素は、MIは位置、トリップが完了ソート選択したこのセンチネルリンパ節の効果についてである、再帰的方法の後の最初の半呼の後半ソート(および周知の速い同じ行)。
第三に、特定の実装は、次のマクロコード実装スワップ機能は、「+」演算子によってスワップのパラメータ、コンパクトロジックによって定義されます。
1、ソートロジック
1 #ifndefの__ALGO_SORT_QUICK_SORT_IMPROVED_H__ 2 の#define __ALGO_SORT_QUICK_SORT_IMPROVED_H__ 3 4の#include <ベクトル> 5の#include <iostreamの> 6 使用して 名前空間をSTD。 7 8 の#defineスワップ(B)({\ 9 typeof演算()TMP = (); \ 10 ()= (B); \ 11 (B)= TMP;}) 12 13テンプレート<型名タイプ> 14 静的 int型 partion(スタンダード::ベクトル<タイプ>・elems、INT低い、INTの高いです) 15 { 16 種類ピボット= elems [低]。 17 int型 MI = 低いです。 18 のための(INTは iが+ロー= 1 ; iが<=高; iが++ ) 19 { 20 であれば(elems [I] < ピボット) 21 { 22 // ++ MI。 23 スワップ(elems [++ MI]、elems [I])。 24 } 25 } 26 スワップ(elems [MI]、elems [低])。 27 リターンマイル。 28 } 29 30テンプレート<型名タイプ> 31 空隙 quick_sort_improved(スタンダード::ベクトル<タイプ>・elems、INT低い、INTの高い) 32 { 33 であれば(ロー< 高い) 34 { 35 INT MI = partion(elems、低、高)。 36 quick_sort_improved(elems、低、MI - 1 )。 37 quick_sort_improved(elems、MI + 1 、高)。 38 } 39 } 40 41 #ENDIF
2、テストプログラム
1つの ベクトル< ダブル > NUMS { 18.1、16.12、32.21、12.22、13.1、53.21、221.5、354、123、42、22.11、33 }。 2 quick_sort_improved < ダブル >(NUMS、0、nums.size() - 1 )。 3 用(INT iは= 0 ; I <nums.size()は、i ++ ) 4 { 5 COUT << NUMS [I] <<" " ; 6 } 7 COUT << ENDL。
3、テスト出力
YG @ YG-PC:〜/ワークスペース/アルゴ/ SRC /ソート/ insertSort $ ./a。アウト 6.52013e-319 6.52013e-319 6.52013e-319 12.22 12.22 16.12 33 0 0 0 42 42
4.分析:上記の結果から、試験結果は、予想される出力、混乱に応じていません。
第四に、リマスター
プラス++オペレータで入ってくるマクロ定義を使用することで、問題の嘘は、マクロ定義に精通している人は確かに同様の問題があったことをデバッグ情報の多くは、;現在の問題は、マクロ定義式は複数回表示され、 ++は確かに望ましい結果ではありません数回、呼び出されます。少し理由を知っているように変更します。
テンプレート<型名タイプ> 静的 INT partion(スタンダード::ベクトル<タイプ>・elems、INT低い、INT 高い) { タイプピボット = elems [低]。 int型 MI = 低いです。 以下のために(INT iが= +ロー1 ; I <=高; I ++ ) { 場合(elems [I] < ピボット) { ++ MI。 スワップ(elems [MI]、elems [I])。 } } スワップ(elems [MI]、elems [低])。 返すマイルを。 }
テスト出力:正しい、期待に沿って
YG @ YG-PC:〜/ワークスペース/アルゴ/ SRC /ソート/ insertSort $ ./a。うち 12.22 13.1 16.12 18.1 22.11 32.21 33 42 53.21 123 221.5 354
V.の概要
毎日のコードマクロ定義スワップ上に使用されるように時々実装は、低レベルのエラーの多くを回避したとしても、避けることはできない。しかし、上記のようにマクロ定義が、依然として望まれることがたくさんある、コンパイラも警告を与えることはありません、それはまた、実行正常に実行することができますが、パスは何とかエラーの結果であり、いくつかの闘争を通じて、地元のマクロ定義を使用した後、この操作を回避しなければならない理由を見つけるために。