跳到主要内容

名古屋工業大学 工学研究科 情報工学専攻 2014年8月実施 問題22 情報科学 II

Author​

祭音Myyura (co-authored with GPT 5.6 SOL)

Description​

II NN 個の相異なる自然数値が配列 AA として与えられるとする(N>1N>1)。このとき,配列の値を昇順にソートするアルゴリズムの擬似コードを以下に示す。

1:  int A[0..N-1];

2: sort(A, low, high) {
3: if (low < high) {
4: x = A[low];
5: i = low; j = high;
6: while (i <= j) {
7: while (A[i] < x) i++;
8: while (A[j] > x) j--;
9: if (i <= j) {
10: swap(A, i, j);
11: i++; j--;
12: }
13: }
14: /* 時点 P */
15: sort(A, low, j);
16: sort(A, i, high);
17: }
18: }

この擬似コードは,sort(A, 0, N-1) を実行することで,配列 AA 中の値が昇順にソートされる。なお,擬似コード中で使われている手続き swap は以下の処理を行うものとする。

  • swap(A, a, b):配列 AA における A[a]A[a] の値と A[b]A[b] の値を入れ替える。

このとき,次の (1)〜(4) の問いについて答えよ。

(1) この擬似コードで実現されているソーティングアルゴリズムの名前を答えよ。

(2) N=10N=10 とし,sort(A, 0, N-1) を実行することを考える。配列 AA の初期値が以下のとおりであるとする。

A[0]A[1]A[2]A[3]A[4]A[5]A[6]A[7]A[8]A[9]
18219134531938246

このとき,擬似コードの実行が初めて時点P(14行目)に到達したときにおける配列 AA の内容を書け。

(3) いま,上記の擬似コードの4行目を以下の命令に書き換える。

4:  x = median(A, low, high);

ここで,関数 median は以下の処理を行うものとする。

  • median(A, a, b):b−a=m−1 (m≥1)b-a=m-1\ (m\ge1) であるような引数 a,ba,b に対して,A[a],A[a+1],…,A[b]A[a],A[a+1],\ldots,A[b] の中から ⌈m/2⌉\lceil m/2\rceil 番目に小さい値を返す。ただし,天井記号 ⌈x⌉\lceil x\rceil は実数 xx 以上の値を持つ最小の整数を表すものとする。

median(A, a, b) の実行時間が Θ(m)\Theta(m) であるとする。このとき,上述の書き換えを行った擬似コードにより実現されるアルゴリズムの最悪時実行時間を Θ\Theta 記法を用いて書け。

(4) (3) で示した書き換えを行わなかった場合を考える。このとき,入力配列 AA の要素数を nn として,擬似コードにより実現されるアルゴリズムの最悪時実行時間を Θ\Theta 記法を用いて書け。また,実行時間が漸近的に最悪となる入力配列 AA はどのようなものか,理由とともに説明せよ。

题目描述​

II 假设数组 AA 给出 NN 个互不相同的自然数(N>1N>1)。下面给出将数组元素按升序排序的算法伪代码。

1:  int A[0..N-1];

2: sort(A, low, high) {
3: if (low < high) {
4: x = A[low];
5: i = low; j = high;
6: while (i <= j) {
7: while (A[i] < x) i++;
8: while (A[j] > x) j--;
9: if (i <= j) {
10: swap(A, i, j);
11: i++; j--;
12: }
13: }
14: /* 时点 P */
15: sort(A, low, j);
16: sort(A, i, high);
17: }
18: }

执行 sort(A, 0, N-1) 后,数组 AA 中的值按升序排列。伪代码中的过程 swap 执行以下处理。

  • swap(A, a, b):交换数组 AA 中 A[a]A[a] 与 A[b]A[b] 的值。

回答下列 (1) 至 (4) 问。

(1) 写出该伪代码实现的排序算法名称。

(2) 令 N=10N=10,考虑执行 sort(A, 0, N-1)。设数组 AA 的初值如下。

A[0]A[1]A[2]A[3]A[4]A[5]A[6]A[7]A[8]A[9]
18219134531938246

写出伪代码执行首次到达时点 P(第14行)时数组 AA 的内容。

(3) 将上述伪代码的第4行改为以下指令。

4:  x = median(A, low, high);

其中函数 median 执行以下处理。

  • median(A, a, b):对于满足 b−a=m−1 (m≥1)b-a=m-1\ (m\ge1) 的参数 a,ba,b,从 A[a],A[a+1],…,A[b]A[a],A[a+1],\ldots,A[b] 中返回第 ⌈m/2⌉\lceil m/2\rceil 小的值。上取整符号 ⌈x⌉\lceil x\rceil 表示不小于实数 xx 的最小整数。

设 median(A, a, b) 的运行时间为 Θ(m)\Theta(m)。请用 Θ\Theta 记法写出修改后的伪代码所实现算法的最坏运行时间。

(4) 考虑没有进行第 (3) 问修改的情况。设输入数组 AA 的元素数为 nn,请用 Θ\Theta 记法写出该算法的最坏运行时间,并说明什么样的输入数组 AA 会使运行时间在渐近意义下最坏,以及相应理由。

Kai​

(1)​

基準値を用いて配列を二分し、各部分を再帰的に整列しているので、

クイックソート\boxed{\text{クイックソート}}

である。

(2)​

最初の呼出しでは x=A[0]=18x=A[0]=18 である。

  • A[0]=18A[0]=18 と A[9]=6A[9]=6 を交換する。
  • 左側では A[1]=21A[1]=21 で止まり、右側では 1818 より大きい値を飛ばして A[4]=4A[4]=4 で止まるので、A[1]A[1] と A[4]A[4] を交換する。
  • その後、i=4,j=3i=4,j=3 となって反復が終了する。

したがって、最初の時点 P における配列は

[6,4,9,13,21,53,19,38,24,18]\boxed{[6,4,9,13,21,53,19,38,24,18]}

である。

(3)​

基準値は中央順位の値である。分割後の部分配列の大きさを nL,nRn_L,n_R とすると、要素が相異なることから

nL+nR≤n,max⁡(nL,nR)≤⌈n/2⌉+1n_L+n_R\le n,\qquad \max(n_L,n_R)\le \lceil n/2\rceil+1

である。median は O(n)O(n) であり、分割処理そのものは Θ(n)\Theta(n) である。したがって再帰の深さは Θ(log⁡n)\Theta(\log n)、各再帰レベルの処理量は Θ(n)\Theta(n) なので、

T(n)=Θ(nlog⁡n)\boxed{T(n)=\Theta(n\log n)}

である。

(4)​

先頭要素 A[low] が基準値である。各部分配列でこの値が最小値になると、分割後の大きさが 00 と n−1n-1 になり、

T(n)=T(n−1)+Θ(n)T(n)=T(n-1)+\Theta(n)

となる。したがって、

T(n)=Θ(n2)\boxed{T(n)=\Theta(n^2)}

である。この状況を生じる入力の例は、相異なる値が昇順または降順に並んだ配列である。特に昇順の場合、各再帰呼出しでも先頭要素が最小値となり、部分配列が一要素ずつしか縮まない。

Reference​