DSA のクラスを受講してから 10 年近くになります。ウィキペディアの並べ替えアルゴリズムのリストを調べましたが、これほど目立ったものはありません。これはプライオリティ キューの実装の一部であり、並べ替えの一部はプッシュ関数 ( EnQueue
) で発生し、もう 1 つはポップ関数 ( DeQueue
) で発生するようです。
これが元のMathematicaコードですが、ほとんどの人はMathematicaに慣れていないので、各関数の下を少し翻訳しました。
EnQueue[q : queue[ar_, n_, pred_], val_] := Module[{i, j},
If[n == Length[ar], ar = Join[ar, makeArray@Length@ar]];
n++; ar[[n]] = val;
i = n;
While[True,
j = Quotient[i, 2];
If[j < 1 || pred[ar[[j]], ar[[i]]],
Break[]
];
ar[[{i, j}]] = {ar[[j]], ar[[i]]};
i = j;
];
q
]
このEnQueue
関数は、最初に要素数がn
heap のサイズに達しているかどうかを確認し、達しているar
場合はヒープを 2 倍にします。次に、要素の数を増やし、新しい要素をそのインデックスに格納します( Mathematicaのインデックスは0ベースではなく1ベースです)。次に、(新しい要素の) そのインデックスに設定し、にi
設定するループに入ります。つまり、ヒープの中央にある要素です。ここで、 if (これは、私が知る限り、 if (中間の要素)が(新しい要素) の前にあることを確認することと同じです)、ブレークします。それ以外の場合は、とで要素を交換しますj
floor(i/2)
j < 1
i == 1
ar[j]
ar[i]
i
j
、そして続けます。そのため、2 回目の反復では、中央をi
指すことから始め、 4 分の 1 を指すようにします。j
DeQueue[queue[ar_, n_, pred_]] :=
Module[{i, j, res = ar[[1]]},
ar[[1]] = ar[[n]]; ar[[n]] = Null; n--;
j = 1;
While[j <= Quotient[n, 2],
i = 2 j;
If[i < n && pred[ar[[i + 1]], ar[[i]]],
i++
];
If[pred[ar[[i]], ar[[j]]],
ar[[{i, j}]] = {ar[[j]], ar[[i]]};
];
j = i];
res]
一方、ヒープの前面を戻し、ヒープの背面DeQueue
を前面に移動します (そして、背面の設定を解除し、要素の数を減らします)。次に、前を指すことから始まり、double に設定することから始まるループに入ります。範囲内(要素を指している) であるが、次の要素に関して順不同である場合、インクリメントされます。が (フロントに対して、つまり、フロントがに対して順不同である場合)の場合、2 つの位置が交換され、 があった位置に設定されます。真ん中を通過するまでループを続けます。j
i
j
i
i
i
j
i
j
i
j
上記の太字の部分がほとんどで、わかりません。でヒープの半分をソートし、 で新しい要素のソートの一部を行っていると思いますが、よくわかりません...DeQueue
EnQueue