第二章 算法入门(2)

2.3 算法设计 (合并排序)

插入排序使用的是增量(incremental)方法。

另一种设计策略,叫做“分治法”(divide-and-conquer)。分制算法的优点之一是很容易确定运行时间

分治策略:将原问题划分成为n个规模较小而结构与原问题相似的子问题;递归的解决这些子问题,然后再合并其结果,就得到原问题的解。

分制模式在每一层递归上都有三个步骤:分解(divide),解决(conquer),合并(combine)。  

合并排序(merge sort)的关键步骤在于合并两个已排序子序列。MERGE过程的时间代价是theta(n)。

伪代码实现MERGE过程:(避免检查是否每一个堆都是空的,在每一堆的底部放上一张“哨兵牌”(sentinel card),利用∞来作为哨兵值)。

 

MERGE(A, p, q, r)
 1  n1 ← q - p + 1
 2  n2 ← r - q
 3  create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1]
 4  for i ← 1 to n1
 5       do L[i] ← A[p + i - 1]
 6  for j ← 1 to n2
 7       do R[j] ← A[q + j]
 8  L[n1 + 1] ← ∞
 9  R[n2 + 1] ← ∞
10  i ← 1
11  j ← 1
12  for k ← p to r
13       do if L[i] ≤ R[j]
14             then A[k] ← L[i]
15                  i ← i + 1
16             else A[k] ← R[j]
17                  j ← j + 1

 

这个很好理解。

现在可将MERGE过程作为合并程序中一个子程序来使用。

伪代码实现MERGE-SORT(A,p,r):

MERGE-SORT(A, p, r)
1 if p < r
2   then q ← ⌊(p + r)/23        MERGE-SORT(A, p, q)
4        MERGE-SORT(A, q + 1, r)
5        MERGE(A, p, q, r)

看图示很明确:

 

 

练习题:2.3-7

 

Describe a Θ(n lg n)-time algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x.

请给出一个运行时间为 Θ(n lg n)的算法,使之能在给定一个由n个整数构成的集合S和另一个整数x时,判断出S中是否存在两个其和等于x的元素。

 1 Input: An array A and a value x.
 2 Output: A boolean value indicating if there is two elements in A whose sum is x.
 3 A <- SORT(A)
 4 n <- length[A]
 5 for i to n do
 6     if A[i] > 0 and BINARY-SEARCH(A;A[i] - x; 1; n) then
 7         return true
 8     end if
 9 end for
10 return false        

思考题2-4 逆序对

Let A[1 n] be an array of n distinct numbers. If i < j and A[i] > A[j], then the pair (i, j) is called an inversion of A.

  1. List the five inversions of the array 2, 3, 8, 6, 1.

  2. What array with elements from the set {1, 2, . . . , n} has the most inversions? How many does it have?

  3. What is the relationship between the running time of insertion sort and the number of inversions in the input array? Justify your answer.

  4. Give an algorithm that determines the number of inversions in any permutation on n elements in Θ(n lg n) worst-case time. (Hint: Modify merge sort.)

    d)给出一个算法,它能用Θ(n lg n)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数目(提示:修改合并程序)。

    根据提示,利用合并程序。很显然,如果L暴露的比R暴露的大, 那么就是逆序对,我们可以统计其次数,则对应是逆序对数目。

COUNT-INVERSIONS.A; p; r/
inversions D 0
if p < r
    q D b.p C r/=2c
    inversions D in ersions C COUNT-INVERSIONS.A; p; q/
    inversions D in ersions C COUNT-INVERSIONS.A; q C 1; r/
    inversions D in ersions C MERGE-INVERSIONS.A; p; q; r/
return inversions
 1 Selected Solutions for Chapter 2: Getting Started
 2 MERGE-INVERSIONS.A; p; q; r/
 3 n1 = q - p + 1
 4 n2 = r - q
 5 let L[1 : : n1 + 1] and R[1 .. n2 + 1] be new arrays
 6 for i = 1 to n1
 7     L[i ] = A[p + i - 1 8 for j = 1 to n2
 9     R[j]  = A[q + j] 
10 L[n1 + 1] =11 R[n2 + 1] =12 i = 1
13 j = 1
14 inversions = 0
15 counted = FALSE
16 for k = p to r
17     if counted == FALSE and ROEj  < LOEi 
18         inversions = inversions + n1 - i + 1
19         counted = TRUE
20     if L[i] <= R[j] 
21         A[k] = L[i] 
22         i = i + 1
23     else A[k] = R[j] 
24         j = j + 1
25         counted = FALSE
26 return inversions         

 

 

 

 

 

posted @ 2012-11-21 10:49  呲牙猫  阅读(446)  评论(0编辑  收藏  举报