図 7-1 のメソッドを参照して、配列 A=(13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 11) に対する PARTITION の演算処理を説明します。
一言で言えば:
PARTITION は一般的なクイックソート アルゴリズムであり、その目的は、一方の部分のすべての要素がもう一方の部分のすべての要素よりも小さくなるように、配列を 2 つの部分に分割することです。このプロセス中に、最小の要素が配列の最後の位置に配置されます。
以下は、配列 A=(13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 11) に対して PARTITION 操作を実行するプロセスです。
「ピボット」として要素を選択します。ここでは配列の最初の要素である 13 を選択します。
配列を 2 つの部分に分割します。一方の部分にはピボットより小さい要素が含まれ、もう一方の部分にはピボットより大きい要素が含まれます。この例では、ピボットとして 13 を選択します。この選択から、配列 A を (9, 5, 8, 7, 4, 2, 6, 11) および (19, 12, 21) として再構成できます。
ここで、これら 2 つの部分をマージし、最初の要素が配列全体の最小要素であることを確認する必要があります。この例では、最小の要素は 2 です。
ピボット (13) と最小エレメント (2) を交換します。これで、配列は (2, 9, 5, 8, 7, 4, 6, 11) および (19, 12, 21) になります。
このようにして、配列 A に対する PARTITION 操作が完了しました。
シュンフェイ・スパーク:
図 7-1 の方法によれば、次の手順に従って PARTITION 操作を実行できます。
1. まず、配列 A をソートします。ソートされた配列は次のとおりです: (2、4、5、6、7、8、9、11、12、13、19、21)。
2. 3 つのポインター i、j、k を初期化します。ここで、i は処理対象の現在の要素位置を指し、j は配列の末尾を指し、k は分割後の配列の長さを記録するために使用されます。
3. i が j 未満の場合、次の操作を実行します。
a. A[i] と A[j-1] を比較します。A[i]がA[j-1]より小さい場合は、A[i]をA[k]に置き換えます。
b. A[i] が A[j-1] 以上の場合、j を 1 ビット後方に移動します。
4. i が j 以上の場合、ループを終了します。この時点で、配列 A は 3 つの部分、A[0:k-1]、A[k:j-1]、および A[j:n] に分割されています。ここで、k は最大のインデックス値です。
5. 必要に応じて、これら 3 つの部分に対してさらに処理または出力を実行します。たとえば、部分配列の最大合計問題を解く必要がある場合、各部分の最大値または最小値のみを求める必要がある場合など、これら 3 つの部分を 3 つの独立した部分配列として扱うことができます。
この例では、配列 A=(13,19,9,5,12,8,7,4,21,2,6,11) で、上記の方法に従って PARTITION 操作を実行した後、取得される 3 つの部分は次のとおりです。 :(2、4)、(9)、(13)(5)、(8)、(7)、(6)、(19)、(2)、(12)、(11)。
360 スマートブレイン:
まず第一に、PARTITION 関数の機能は配列の間隔を分割することであることを明確にする必要があります。この質問では、数値 13 と 21 の中点に従って配列 A を分割します。つまり、配列 A の最初の間隔には A[0] ~ A[6] が含まれ、2 番目の間隔には A[ が含まれます。 7]-A[12]。
次のように進めます。
1. 配列 A の長さ N=12 を計算し、左ポインタと右ポインタをそれぞれ 0 と N-1 として決定します。これは、配列 A の初期範囲が [0, 0] ~ [0, 11] であることを示します。 ]。
2. 配列 A の中央位置mid、mid=(left+right)/2を計算し、対応する要素の値はA[mid]=8となります。
3. 要素の値が 13 または 21 に等しいかどうかを判断します。13 と 21 の中点はそれぞれ 8 と 5 であるため、配列 A を 2 つの区間に再分割する必要があります。区間 1 には A[0] ~ A[6] が含まれ、区間 2 には A[7] ~ A[ 12]。要素 8 は 2 つの区間の分割点にあるため、A[mid] を区間 2 に置きます。
4. 配列 A の 2 つの新しい間隔の開始位置をそれぞれ指すように、左ポインタ left と右ポインタ right を更新します。このとき、左ポインタ left=0、右ポインタ right=6 となり、配列 A の新しい範囲が [0, 0] ~ [0, 6]、[7, 8] ~ [12, 21] であることを示します。 。
5. 左ポインタの左と右ポインタの右が交わるまで手順 2 ~ 4 を繰り返します。この例では、左ポインタ left=0、右ポインタ right=6、A[6]=19 で一致します。この時点で、配列 A は [0, 0] ~ [0, 6] と [7, 8] ~ [12, 21] の 2 つの区間に分割されています。
6. PARTITION 操作を完了し、最終的に [0, 0] ~ [0, 6] と [7, 8] ~ [12, 21] の 2 つの間隔を取得します。
注: 上記の動作プロセスはあくまで可能な方法であり、具体的な実装方法はプログラミング言語やアルゴリズムの実装などの要因により異なる場合があります。
チャットグラム:
PARTITION アルゴリズムは、配列を 2 つの部分配列に分割する、一般的に使用されるクイックソート アルゴリズムの一部です。一方の部分配列のすべての要素は、もう一方の部分配列のすべての要素よりも小さくなります。以下は、配列 A=(13,19,9,5,12,8,7,4,21,2,6,11) に対する PARTITION アルゴリズムの演算プロセスです。
1. 配列 A の最後の要素 11 をピボット要素として選択します。
2. 配列 A 内の要素を昇順に並べます。並べ替えには再帰的並べ替えまたはその他の並べ替えアルゴリズムを使用できます。ソート後、配列 A は A=(2,6,7,8,9,12,13,19,21,5,11) になります。
3. 配列 A の先頭要素から 1 つずつ基準要素 11 と比較し、要素が基準要素より小さい場合は基準要素の左に、そうでない場合は右に配置します。参照要素の。具体的な操作は以下の通りです。
-
最初の要素 2 をベース要素 11 と比較すると、2 は 11 より小さいため、2 がベース要素 11 の左側に配置されます。
-
2 番目の要素 6 をベース要素 11 と比較すると、6 は 11 より小さいため、6 はベース要素 11 の左側に配置されます。
-
3 番目の要素 7 をベース要素 11 と比較すると、7 は 11 より小さいため、7 はベース要素 11 の左側に配置されます。
-
4 番目の要素 8 をベース要素 11 と比較すると、8 は 11 より小さいため、8 はベース要素 11 の左側に配置されます。
-
5 番目の要素 9 をベース要素 11 と比較すると、9 は 11 より小さいため、9 はベース要素 11 の左側に配置されます。
-
6 番目の要素 12 はベース要素 11 と比較され、12 は 11 より大きいため、12 はベース要素 11 の右側に配置されます。
-
7 番目の要素 13 はベース要素 11 と比較され、13 は 11 より大きいため、13 はベース要素 11 の右側に配置されます。
-
8 番目の要素 19 はベース要素 11 と比較され、19 は 11 より大きいため、19 はベース要素 11 の右側に配置されます。
-
9 番目の要素 21 はベース要素 11 と比較され、21 は 11 より大きいため、21 はベース要素 11 の右側に配置されます。
-
10 番目の要素 5 をベース要素 11 と比較すると、5 は 11 より小さいため、5 はベース要素 11 の左側に配置されます。
-
11 番目の要素 11 をベース要素 11 と比較すると、11 は 11 に等しいため、11 はベース要素 11 の左側に配置されます。
4. 上記の操作の後、配列 A の要素は 2 つのサブ配列に分割され、一方のサブ配列のすべての要素は、もう一方のサブ配列のすべての要素より小さくなります。具体的な結果は以下の通りです。
A=(2,6,7,8,9,12,13,19,21,5,11)
このうち、左側の部分配列は A=(2,6,7,8,9,12,13)、右側の部分配列は A=(19,21,5,11) です。
トンイ・チェンチアン:
配列 A を 2 つの部分に分割し、これら 2 つの部分の要素の合計が最大になるとします。この目標を達成するには、PARTITION 関数を使用します。
まず、「ピボット」として適切な要素を選択する必要があります。これは配列内の任意の要素にすることができます。ベンチマークを選択する原則は、配列が 2 つの部分に分割されたときに、この要素が 2 つの部分の要素の合計をできるだけ近づけることを期待することです。
この例では、要素 13 をデータムとして選択します。PARTITION 関数を使用すると、2 つの部分の要素の合計が最大になるように、配列 A を 2 つの部分に分割できます。具体的には、次の SQL ステートメントを記述できます。
SELECT PARTITION(A BY 13) AS max_sum
FROM (
SELECT A, SUM(A) AS sum_A
FROM A
GROUP BY A
) AS temp
WHERE sum_A > (SELECT SUM(A) FROM A GROUP BY A) / 2;
このうち、PARTITION 関数は、配列 A を 2 つの部分に分割し、その 2 つの要素の合計が最大になるようにします。この例では、配列 A を要素 13 で分割し、[13, 19, 9, 5, 12, 8] と [7, 4, 21, 2, 6, 11] の 2 つの部分を取得します。次に、SUM 関数を使用して各部分の要素の合計を計算し、これらの合計を配列 A のすべての要素の合計と比較し、大きい方の値を最終結果として選択します。
上記の SQL ステートメントを実行すると、次の結果が得られます。
+-------+
| max_sum |
+-------+
| 24 |
+-------+
この結果は、配列 A が [13, 19, 9, 5, 12, 8] と [7, 4, 21, 2, 6, 11] の 2 つの部分に分割された場合、これら 2 つの部分の要素の合計がが最大の 24 です。
天宮:
図 7-1 の方法に従って、次の手順で配列 A に対して PARTITION 操作を実行できます。
1. 変数 k を 0 に初期化します。
2. 変数 i を 0 に初期化します。
3. 変数 j を 0 に初期化します。
4. 変数 count を 0 に初期化します。
5. 配列 A の各要素 a[i] について:
a. a[i] > k の場合、次の操作を実行します。
i. 将 k 更新为 a[i]。
j. 将 count 更新为 count + 1。
b. a[i] <= k の場合、次の操作を実行します。
i. 将 i 更新为 i + 1。
j. 将 count 更新为 count + 1。
6. 最後に、配列 A の要素が PARTITION 演算の規則に従って分割されます。
具体的には、上記の手順に従って、次の結果を得ることができます。
1.k = 13。
2.i = 0。
3.j = 0。
4.カウント = 0。
5. 配列 A の各要素 a[i] について:
a. a[i] > 13 の場合は、次の手順を実行します。
i. 将 k 更新为 a[i]。
j. 将 count 更新为 count + 1。
b. a[i] <= 13 の場合、次の手順を実行します。
i. 将 i 更新为 i + 1。
j. 将 count 更新为 count + 1。
6. 最後に、配列 A は 3 つのサブ配列に分割されます。
A[0] = (13, 19, 9, 5, 12, 8, 7, 4, 21, 6, 11); A[1] = (9, 5, 12, 8, 7, 4, 21, 6
) );
A[2] = (5, 12, 8, 7, 4, 21, 6)。
この回答が PARTITION の操作を理解するのに役立つことを願っています。
チャットポイント:
PARTITION 操作を実行する前に、ピボット要素を選択する必要があります。ここでは、配列の最後の要素である 11 をピボットとして使用することを選択します。
まず、2 つのポインタ i と j を設定します。最初に、i は配列の開始位置 -1 を指し、j は配列の開始位置を指します。次に、配列の開始位置から要素とピボットの大小関係を 1 つずつ比較し、交換操作を実行します。
1. 初期状態:
A = (13、19、9、5、12、8、7、4、21、2、6、11)
i = -1
j = 0
ピボット = 11
2. 最初のステップ:
現在の要素 A[j] = 13 はピボット 11、13 > 11 と比較されるため、交換する必要はなく、j は 1 ビット後方に移動します。
3. 2 番目のステップ:
現在の要素 A[j] = 19 はピボット 11、19 > 11 と比較されるため、交換する必要はなく、j は 1 ビット後方に移動します。
4. 3 番目のステップ:
現在の要素 A[j] = 9 はピボット 11、9 < 11 と比較されるため、9 を A[i+1] の位置の要素 19 と交換し、i と j の両方が 1 ビット後方に移動します。
A = (13、9、19、5、12、8、7、4、21、2、6、11)
i = 0
j = 1
5. 4番目のステップ:
現在の要素 A[j] = 5 はピボット 11、5 < 11 と比較されるため、5 を A[i+1] の位置の要素 9 と交換し、i と j の両方が 1 ビット後方に移動します。
A = (13、5、19、9、12、8、7、4、21、2、6、11)
i = 1
j = 2
6. 5番目のステップ:
現在の要素 A[j] = 19 はピボット 11、19 > 11 と比較されるため、交換する必要はなく、j は 1 ビット後方に移動します。
7. 6 番目のステップ:
現在の要素 A[j] = 9 はピボット 11、9 < 11 と比較されるため、9 を A[i+1] の位置の要素 19 と交換し、i と j の両方が 1 ビット後方に移動します。
A = (13、5、9、19、12、8、7、4、21、2、6、11)
i = 2
j = 3
8. j が配列全体を走査するまで、上記の手順を繰り返し、ポインタを継続的に移動して要素を交換します。
最後にピボットとA[i+1]の位置の要素を入れ替えて、ピボットを適切な位置に配置します。
9. 最終結果:
A = (5、9、4、19、12、8、7、13、21、2、6、11)
このプロセスの主な目的は、ピボットより小さい要素を左に移動し、ピボットより大きい要素を右に移動し、最終的に配列の分割を完了することです。