名古屋大学 情報学研究科 複雑系科学専攻 2018年8月実施 情3
Author
祭音Myyura
Description
相異なる 個の自然数を、インデックス から の一次元配列 に格納する。
に対し、列中の 番目に小さい値を返す関数 k_th を、次の関数 partition を用いて作る。
partition(A,i,j) は、 なら を返す。 なら pivot = A[j] とし、区間 を並べ替えて、pivot が格納されたインデックス を返す。返却時には
が成り立つ。
手続き `partition(A,i,j)`
1. もし i と j が等しければ、i を返し、手続きを終了する。
2. 変数 pivot に A[j] の値を代入する。
3. 変数 id に i の値を代入する。
4. 変数 ip に i の値を代入する。
5. 繰り返し begin
6. もし id の値と j の値が等しければ、繰り返しを終了する。
7. もし A[id] の値が pivot の値以下であれば、
8. begin
9. A[ip] の値と A[id] の値を交換する。
11. ip + 1 の値を ip に代入する。
12. end
13. id + 1 の値を id に代入する。
14. 繰り返し end
15. A[ip] の値と A[j] の値を交換する。
16. ip の値を返し、手続きを終了する。
[1] の配列
| インデックス | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| 50 | 10 | 80 | 30 | 70 | 20 | 40 | 60 |
に対して partition(B,3,7) を実行する。id、ip または配列 に対する操作が行われる行番号と、その操作後の状態をすべて示し、返り値も答えよ。見かけ上、配列が変化しない交換も省略しないものとする。
[2] 配列 が次を満たすとする。
- インデックスが より小さい全要素は、インデックスが 以上の全要素より小さい。
- インデックスが より大きい全要素は、インデックスが 以下の全要素より大きい。
このとき partition(A,i,j) が を返したなら、配列 における 番目に小さい自然数を求め、その理由を述べよ。
[3] 問 [2] の条件の下で とする。partition(A,i,j) が を返したとき、
- なら、 番目に小さい自然数はどのインデックス範囲にあるか。
- なら、 番目に小さい自然数はどのインデックス範囲にあるか。
[4] k_th(A,1,n,k) が 番目に小さい自然数を返すように、次の空欄を埋めよ。
手続き k_th(A,i,j,k)
1. 変数 p に partition(A,i,j) が返す値を代入する。
2. もし(ア)であれば、(イ)を返し、手続きを終了する。
3. もし(ウ)であれば、(エ)を返し、手続きを終了する。
4. もし(オ)であれば、(カ)を返し、手続きを終了する。
Kai
[1]
pivot = B[7] = 40 である。
id=3: なので交換せず、idを 4 にする。id=4: なので と を交換し、ipを 4 にする。id=5: なので交換しない。id=6: なので と を交換し、ipを 5 にする。id=7=jで反復を終え、 と を交換する。
| 行番号 | id の値 | ip の値 | 配列 の要素の並び |
|---|---|---|---|
| 3 | 3 | 未定 | 50 10 80 30 70 20 40 60 |
| 4 | 3 | 3 | 50 10 80 30 70 20 40 60 |
| 12 | 4 | 3 | 50 10 80 30 70 20 40 60 |
| 9 | 4 | 3 | 50 10 30 80 70 20 40 60 |
| 10 | 4 | 4 | 50 10 30 80 70 20 40 60 |
| 12 | 5 | 4 | 50 10 30 80 70 20 40 60 |
| 12 | 6 | 4 | 50 10 30 80 70 20 40 60 |
| 9 | 6 | 4 | 50 10 30 20 70 80 40 60 |
| 10 | 6 | 5 | 50 10 30 20 70 80 40 60 |
| 12 | 7 | 5 | 50 10 30 20 70 80 40 60 |
| 14 | 7 | 5 | 50 10 30 20 40 80 70 60 |
したがって、
であり、終了時の配列は
である。
[2]
partition の終了時には
であり、自然数は相異なるので、
となる。
さらに仮定より、
である。したがって より小さい要素はちょうど 個である。
よって、 番目に小さい自然数は
である。これは partition 呼出し前の pivot、すなわち元の の値でもある。
[3]
問 [2] より、 は配列全体で 番目に小さい。
-
のとき、 番目に小さい自然数は
の範囲にある。
-
のとき、 番目に小さい自然数は
の範囲にある。
[4]
空欄は次の通りである。
| 空欄 | 解答 |
|---|---|
| (ア) | |
| (イ) | |
| (ウ) | |
| (エ) | k_th(A,i,p-1,k) |
| (オ) | |
| (カ) | k_th(A,p+1,j,k) |
したがって、完成した手続きは
手続き k_th(A,i,j,k)
1. p に partition(A,i,j) の返り値を代入する。
2. もし p = k であれば、A[p] を返す。
3. もし p > k であれば、k_th(A,i,p-1,k) を返す。
4. もし p < k であれば、k_th(A,p+1,j,k) を返す。
となる。ここで は配列全体における順位であり、再帰呼出しでもインデックスを保持するため、右側を探索するときも などへ変換する必要はない。