算法导论 — 思考题8-5 平均排序

平均排序)假设我们不是要完全排序一个数组,而只是要求数组中的元素在平均情况下是升序的。更准确地说,如果对所有的 i = 1 , 2 , … , n − k i = 1, 2, …, n−k i=1,2,,nk有下式成立,我们就称一个包含 n n n个元素的数组 A A A k k k排序的( k k k-sorted):
       ∑ j = i i + k − 1 A [ j ] k ≤ ∑ j = i + 1 i + k A [ j ] k \frac{\sum_{j=i}^{i+k-1}{A[j]}}{k}≤\frac{\sum_{j=i+1}^{i+k}{A[j]}}{k} kj=ii+k1A[j]kj=i+1i+kA[j]
  a. 一个数组是 1 1 1排序的,表示什么含义?
  b. 给出对数字 1 , 2 , … , 10 1, 2, …, 10 1,2,,10的一个排序,它是 2 2 2排序的,但不是完全有序的。
  c. 证明:一个包含 n n n个元素的数组是 k k k排序的,当且仅当对所有的 i = 1 , 2 , … , n − k i = 1, 2, …, n−k i=1,2,,nk,有 A [ i ] ≤ A [ i + k ] A[i] ≤ A[i+k] A[i]A[i+k]
  d. 设计一个算法,它能在 O ( n l g ( n / k ) ) O(n{\rm lg}(n/k)) O(nlg(n/k))时间内对一个包含 n n n个元素的数组进行 k k k排序。当 k k k是一个常数时,也可以给出 k k k排序算法的下界。
  e. 证明:我们可以在 O ( n l g k ) O(n{\rm lg}k) O(nlgk)时间内对一个长度为 n n n k k k排序数组进行全排序。(提示:可以利用练习6.5-9的结果。)
  f. 证明:当 k k k是一个常数时,对包含 n n n个元素的数组进行 k k k排序需要 Ω ( n l g n ) Ω(n{\rm lg}n) Ω(nlgn)的时间。(提示:可以利用前面解决比较排序的下界的方法。)
  
  
  a.
  一个数组 A A A 1 1 1排序的,说明对所有 i = 1 , 2 , … , n − 1 i = 1, 2, … , n-1 i=1,2,,n1,有 A [ i ] ≤ A [ i + 1 ] A[i] ≤ A[i+1] A[i]A[i+1],这说明这个数组是完全有序的。
  
  b.
     2 1 4 3 6 5 8 7 10 9
  
  c.
  这一问题可以分解为两个命题,对于一个包含 n n n个元素的数组 A A A
  命题a:数组 A A A k k k排序的
  命题b:对所有的 i = 1 , 2 , … , n − k i = 1, 2, …, n−k i=1,2,,nk,有 A [ i ] ≤ A [ i + k ] A[i] ≤ A[i+k] A[i]A[i+k]
  本题的意思是要证明这两个命题是等价的,需要分两步证明。
  (1) 证明:命题a成立可以推导出命题b成立
  如果命题a成立,即数组 A A A k k k排序的,那么对所有的 i = 1 , 2 , … , n − k i = 1, 2, …, n−k i=1,2,,nk,有
     ∑ j = i i + k − 1 A [ j ] k ≤ ∑ j = i + 1 i + k A [ j ] k \frac{\sum_{j=i}^{i+k-1}{A[j]}}{k}≤\frac{\sum_{j=i+1}^{i+k}{A[j]}}{k} kj=ii+k1A[j]kj=i+1i+kA[j]
  将上面的不等式的左边减去右边,得到
     ∑ j = i i + k − 1 A [ j ] k − ∑ j = i + 1 i + k A [ j ] k ≤ 0 \frac{\sum_{j=i}^{i+k-1}{A[j]}}{k}-\frac{\sum_{j=i+1}^{i+k}{A[j]}}{k}≤0 kj=ii+k1A[j]kj=i+1i+kA[j]0
  即
     A [ i ] k − A [ i + k ] k ≤ 0 \frac{A[i]}{k}-\frac{A[i+k]}{k}≤0 kA[i]kA[i+k]0
  于是可以得到 A [ i ] ≤ A [ i + k ] A[i] ≤ A[i+k] A[i]A[i+k]。所以命题a可以推导出命题b。
  (2) 证明:命题b成立可以推导出命题a成立
  命题b成立,说明对所有的 i = 1 , 2 , … , n − k i = 1, 2, …, n−k i=1,2,,nk
     A [ i ] ≤ A [ i + k ] A[i] ≤ A[i+k] A[i]A[i+k]
  将上面的不等式左右两边都加上 A [ i + 1 ] + A [ i + 2 ] + … + A [ i + k − 1 ] A[i+1] + A[i+2] + … + A[i+k−1] A[i+1]+A[i+2]++A[i+k1],得到
     ∑ j = i i + k − 1 A [ j ] ≤ ∑ j = i + 1 i + k A [ j ] \sum_{j=i}^{i+k-1}{A[j]}≤\sum_{j=i+1}^{i+k}{A[j]} j=ii+k1A[j]j=i+1i+kA[j]
  将该不等式左右两边同时除以 k k k,得到
     ∑ j = i i + k − 1 A [ j ] k ≤ ∑ j = i + 1 i + k A [ j ] k \frac{\sum_{j=i}^{i+k-1}{A[j]}}{k}≤\frac{\sum_{j=i+1}^{i+k}{A[j]}}{k} kj=ii+k1A[j]kj=i+1i+kA[j]
  于是,数组 A A A k k k排序的。所以命题b可以推导出命题a。
  
  d.
  根据c的结论,可以考虑将数组 A A A分为 k k k组,每组最多 ⌈ n / k ⌉ ⌈n/k⌉ n/k个元素。
  第 1 1 1组: A [ 1 ] , A [ 1 + k ] , A [ 1 + 2 k ] , … … A[1], A[1+k], A[1+2k], … … A[1],A[1+k],A[1+2k],
  第 2 2 2组: A [ 2 ] , A [ 2 + k ] , A [ 2 + 2 k ] , … … A[2], A[2+k], A[2+2k], … … A[2],A[2+k],A[2+2k],
   … … ……
  第 k k k组: A [ k ] , A [ 2 k ] , A [ 3 k ] , … … A[k], A[2k], A[3k], … … A[k],A[2k],A[3k],
  对每组元素采用运行时间上界为 O ( n l g n ) O(n{\rm lg}n) O(nlgn)的排序算法,例如堆排序或归并排序,即可完成对整个数组的 k k k排序。
  由于每组最多 ⌈ n / k ⌉ ⌈n/k⌉ n/k个元素,因此每一组排序的时间为 O ( ( n / k ) l g ⁡ ( n / k ) ) O((n/k){\rm lg}⁡(n/k)) O((n/k)lg(n/k))。一共有 k k k组,所以总的时间为 O ( n l g ( n / k ) ) O(n{\rm lg}(n/k)) O(nlg(n/k))
  
  e.
  对于一个已经 k k k排序的数组来说,按照上文所述方法进行分组,那么每一组内的元素是有序。要对该数组进行全排序,实际上是将 k k k个有序分组进行合并。因此,可以直接采用练习6.5-9的方法,这里不对该方法进行赘述,请参考链接https://blog.csdn.net/yangtzhou/article/details/84801494。根据练习6.5-9的结果,该方法的时间复杂度为 O ( n l g k ) O(n{\rm lg}k) O(nlgk)
  
  f.
  可以直接套用8.1节的排序决策树模型,不过 k k k排序的决策树包含的叶结点数目有所不同。对于一个有 n n n个元素的数组, k k k排序实际上是排序 k k k组序列,每个序列最多包含 ⌈ n / k ⌉ ⌈n/k⌉ n/k个元素。那么 k k k排序后,数组可能的排列一共有 k ( ⌈ n / k ⌉ ! ) k(⌈n/k⌉!) k(n/k!)种,这也是决策树的叶结点数目。假设该决策树的高度为 h h h,那么它最多包含 2 h 2^h 2h个叶结点。于是有
     k ( ⌈ n / k ⌉ ! ) ≤ 2 h k(⌈n/k⌉!)≤2^h k(n/k!)2h
  对该不等式两边取对数,得到
     h ≥ l g ( k ( ⌈ n / k ⌉ ! ) ) = l g k + l g ( ⌈ n / k ⌉ ! ) = Ω ( ( n / k ) l g = Ω ( ( n / k ) ( l g n − l g k ) ) h≥{\rm lg}(k(⌈n/k⌉!))={\rm lg}k+{\rm lg}(⌈n/k⌉!)=Ω((n/k){\rm lg}=Ω((n/k)({\rm lg}n-{\rm lg}k)) hlg(k(n/k!))=lgk+lg(n/k!)=Ω((n/k)lg=Ω((n/k)(lgnlgk))
  如果 k k k是常数,那么必然有
     h = Ω ( ( n / k ) ( l g n − l g k ) ) = Ω ( n l g n ) h=Ω((n/k)({\rm lg}n-{\rm lg}k))=Ω(n{\rm lg}n) h=Ω((n/k)(lgnlgk))=Ω(nlgn)
  所以,当 k k k是一个常数时,对包含 n n n个元素的数组进行 k k k排序需要 Ω ( n l g n ) Ω(n{\rm lg}n) Ω(nlgn)的时间。

你可能感兴趣的:(算法导论)