QuickSort推导 - The Science of Programming

Edit

学习笔记 读书笔记 Programming

由于近日开发单片机程序的时候,写到一个小循环,不能确定其正确性,进而想到这本书的内容,算是一个小小的回顾。本书的读书笔记参考这篇The Science of Programming
正所谓温故而知新,这次重新摘读又有些新的收获。本想以QuickSort作为一个练习来运用本书的知识,结果尝试了许久,发现越陷越深。最后还是找了书上的例子(书中有QuickSort的例子)。本文最终目标是阐述如何推导QuickSort程序本身。先摘取一些重要的知识点,再利用这些知识点来推导QuickSort。

1. Quantification(量化)[原书4.2节]

  • There exists
    (E i: mi\<n: Ei)
  • For all
    (A i: mi\<n: Ei)
  • Numerial
    (N i: mi\<n: Ei)

他们有以下特性

(E i: mi\<k+1: Ei) = (E i: mi\<k: Ei) V Ek+1
(A i: mi\<n: Ei) = (E i: mi\<n: Ei)
(E i: mi\<n: Ei) = (N i: mi\<n: Ei) 1
(A i: mi\<n: Ei) = (N i: mi\<n: Ei) = n-m

2. 何为wp?[原书第7章]

原书的定义:

The Predicate Transformer wp

The set of all states such that execution of S begun in any one of them is guaranteed to terminate in a finite amount of time in a state satisfying R.

wp通常被用来表达一段程序

或者这样写

  • Q:前条件
  • S:执行代码(原文称为commands)
  • R:后条件

wp的特性

1) wp(S,F) = F
2) wp(S ^ Q) ^ wp(S,R) = wp(S,Q ^ R )
3) if Q then wp(S, Q ) wp(S, R)
4) wp(S wp(S, R)) wp(S ,Q v R)
5) wp(S, Q) V wp(S, R) = wp(S, Q V R) (for deterministic S)

3. 循环检查 (原书第11章)

定义

用数学语言标记一个循环如下:
{Q}
{inv P: the invariant}
{bound t: the bound function}
{init IS: initialization command}
do B1 S1

Bn Sn
od

Invariant

A predicate P that is true before and after each iteration of a loop.

这就是说P在任何情况下都要成立,于是有

  • Q wp(IS, P)
  • P wp(DO, P ^ BB)

Bound

又叫bound function

The function changes at each iteration; the relation remains invariantly true.
each iteration decreases t by at least one,so that termination is guaranteed to occur.

检查bound函数确保循环能结束。

Checklist

非常重要!!!

  1. Q wp(IS, P)
  2. P ^ Bi wp(Si, P)
  3. P ^ BB R
  4. P ^ BB (t > 0)
  5. P ^ Bi wp(“t1:=t; Si“, “t < t1“)

依次验证这5条,就能证明一个循环的正确性了

推测Command

通过后条件R,来推测执行代码(Command)。这就是所谓的Programming as a Goal-Oriented Activity。详情参看原书第14章。

Strategy for developing an alternative command: To invent a guarded command,find a command C whose execution will establish postcondition R in at least some cases; find a Boolean B satisfying Bwp(C,R) and put them together to form B C. Continue to invent guarded commands until the precondition of the construct implies that at least one guard is true. - 原文(14.7)

获得Guard(原书第15章)

所有的编程都应该是结果导向的(这与测试驱动开发TDD的思想暗合)。所以后条件R是最先有的。
其次,通过P BB R能得到BB(即guard)。虽然有公式AB <=> A V B=T,但是B的获得感觉更多是依靠分析而不是推导。具体例子会在本文最后推导Quick Sort中提及。
其中

不过由上式可知,此时的guard还是个总的guard,还需要将之分解为各个Bi

获得不变量Invariant(原书第16章)

书中给了4种方法:

  1. Delete a conjunct. For example, predicate A ^ B ^ C can be weakened to A ^ C
  2. Replace a constant by a variable. For example, predicate x b[1:10], where x is a simple variable,can be weakened to x b[1:i] ^ 110,where i is a fresh variable. Since a new
    variable has been introduced, its possible set of values must be precisely stated.
  3. Enlarge the range of a variable. For example, predicate 5 i < 10 can be weakened to 0 i < 10.
  4. Add a disjunct. For example, predicate A can be weakened to A v B, for some other predicate B.

书中推荐用前三个,根据阅读本书后面部分的经验,最常用的还是第二条。

推导Quick Sort (原书18.2节)

本文以推导快速排序作为结束。
快速排序的核心思想就是不断分割,在小数组中递归的作排序,直到小数组的元素个数少于或等于2个,即可进行直接排序了。所以分成Partition和Sort两部分。

Partition (原书练习16.5)

一次分割的后条件如下
R:

由R获得P

通过上一节中的方法二Replace a constant by a variable.来得到P。
P:

由P BB R推算BB

注意是推算,不是严格的逻辑推导
P (p-q+1=0) R
BB = (p-q+1=0)
BB = (pq-1)

推测command

由QuickSort的基本算法可知,有三个可能的command

  1. q++
  2. p–
  3. swap(b[p], b[q])
    所以现在程序形式如下:
    do pq-1
     if__ p:=p-1
      __ q:=q+1
      __ swap(b[p], b[q])
     fi
    od

由command+P+BB获得Guard

PBBwp(S,P)

  1. S = “p:=p-1”
      wp(S,P) =
  2. S = “q:=q+1”
    过程类似
      wp(S,P)=

对于前半部分的证明如下:
P中有
BB = (pq-1)
q < p q p-1 q+1p
得证
对于后半部分,显而易见需要b[q]x,即

  1. swap(b[p], b[q])
      wp(S,P)=

验证

Q: T
R:

  1. wp(IS, P) =
  2. PBB wp(,P)
    这个显然也是成立的,因为我们的就是这么来的
  3. PBBR
    同上,亦成立
  4. PBB(t>0)
    BB = (pq-1) p-q+10
    又由P有
    qp+1 p-q+10
    t=p-q+1>0
    得证
  5. P wp(“”, “t<t1")
    对于三种,t都显然会变小,所以满足

综上,5条check point都满足,程序正确性可保证

推导

根据快速排序算法可知,对数组排序,即进行若干次分割,直至子区间包含2个元素,即可以进行直接排序。

  • P: s is a set of pairs (i, j) representing disjoint array sections b[i:j] of b. Further,b[0:n—1] is ordered iff all the disjoint partitions given by set s are.
  • IS: s:={(0,n-1)}
  • R: b[0:n-1] are ordered
  • t: n - ordered

快速排序程序如下:
s:={(0,n-1)}
{Invariant: 如上P}
do s{} Choose((i,j),s); s:=s-{(i,j)};
   if j-i \< 2 Sort b[i:j] directly
    j-i 2 Partition(b,i,j,p;);
   fi
od

C代码

最终Quick Sort C代码实现如下:

1.#define N           50
2.#define MAX_SPLIT 50 // This should be logN
3.void swap(int* b, int p, int q)
4.
{
5. b[p]=b[p]+b[q];
6. b[q]=b[p]-b[q];
7. b[p]=b[p]-b[q];
8.}
9.int Partition (int* b, int m, int n)
10.
{
11. assert(n>m);
12. int p=n-1, q=m+1;
13. while (p != q-1)
14. {
15. if (b[p]>x)
16. {
17. p--;
18. }
19. else if (b[q]<=x)
20. {
21. q++;
22. }
23. else if (b[q]<=x && b[p]>x)
24. {
25. swap(b, p ,q);
26. p--;
27. q++;
28. }
29. }
30. return p;
31.}
32.void QuickSort(int* b, int n)
33.
{
34. typedef struct
35. {
36. int start;
37. int end;
38. }Pair s[MAX_SPLIT] = {0};
39. int count = 1; // how many pairs in s
40. s[0].start = 0;
41. s[0].end = n-1;
42. while (count > 0)
43. {
44. Pair p;
45. memcpy(&p, &s[count-1], sizeof(Pair));
46. if(p.end - p.start < 2)
47. {
48. if (p.start > p.end)
49. {
50. swap (b, p.start, p.end);
51. count --;
52. }
53. else
54. {
55. int m = p.start;
56. int n = p.end - p.start + 1;
57. int x = Partition(b, m, n);
58. s[count-1].start = p.start;
59. s[count-1].end = x-1;
60. s[count].start = x+1;
61. s[count].end = p.end;
62. count ++;
63. }
64. }
65. }
66.}
%23QuickSort%u63A8%u5BFC%20-%20The%20Science%20of%20Programming%0A%0A@%28%u5B66%u4E60%u7B14%u8BB0%29%5B%u8BFB%u4E66%u7B14%u8BB0%2C%20Programming%5D%0A%0A%u7531%u4E8E%u8FD1%u65E5%u5F00%u53D1%u5355%u7247%u673A%u7A0B%u5E8F%u7684%u65F6%u5019%uFF0C%u5199%u5230%u4E00%u4E2A%u5C0F%u5FAA%u73AF%uFF0C%u4E0D%u80FD%u786E%u5B9A%u5176%u6B63%u786E%u6027%uFF0C%u8FDB%u800C%u60F3%u5230%u8FD9%u672C%u4E66%u7684%u5185%u5BB9%uFF0C%u7B97%u662F%u4E00%u4E2A%u5C0F%u5C0F%u7684%u56DE%u987E%u3002%u672C%u4E66%u7684%u8BFB%u4E66%u7B14%u8BB0%u53C2%u8003%u8FD9%u7BC7%5BThe%20Science%20of%20Programming%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/c79122e8-c790-44b7-afa4-93eca3ad662e/%29%u3002%0A%u6B63%u6240%u8C13%u6E29%u6545%u800C%u77E5%u65B0%uFF0C%u8FD9%u6B21%u91CD%u65B0%u6458%u8BFB%u53C8%u6709%u4E9B%u65B0%u7684%u6536%u83B7%u3002%u672C%u60F3%u4EE5QuickSort%u4F5C%u4E3A%u4E00%u4E2A%u7EC3%u4E60%u6765%u8FD0%u7528%u672C%u4E66%u7684%u77E5%u8BC6%uFF0C%u7ED3%u679C%u5C1D%u8BD5%u4E86%u8BB8%u4E45%uFF0C%u53D1%u73B0%u8D8A%u9677%u8D8A%u6DF1%u3002%u6700%u540E%u8FD8%u662F%u627E%u4E86%u4E66%u4E0A%u7684%u4F8B%u5B50%uFF08%u4E66%u4E2D%u6709QuickSort%u7684%u4F8B%u5B50%uFF09%u3002%u672C%u6587%u6700%u7EC8%u76EE%u6807%u662F%u9610%u8FF0%u5982%u4F55%u63A8%u5BFCQuickSort%u7A0B%u5E8F%u672C%u8EAB%u3002%u5148%u6458%u53D6%u4E00%u4E9B%u91CD%u8981%u7684%u77E5%u8BC6%u70B9%2C%u518D%u5229%u7528%u8FD9%u4E9B%u77E5%u8BC6%u70B9%u6765%u63A8%u5BFCQuickSort%u3002%0A%0A%5BTOC%5D%0A%0A%23%23%u77E5%u8BC6%u70B9%u68B3%u7406%0A%23%23%231.%20Quantification%uFF08%u91CF%u5316%uFF09%5B%u539F%u4E664.2%u8282%5D%0A%0A*%20There%20exists%20%20%0A%09%28***E***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%0A*%20For%20all%20%20%0A%09%28***A***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%0A*%20Numerial%20%20%0A%09%28***N***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%0A%09%0A%u4ED6%u4EEC%u6709%u4EE5%u4E0B%u7279%u6027%0A%0A%3E%28***E***%20i%3A%20m%24%5Cleq%24i%5C%3Ck+1%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%3D%20%28***E***%20i%3A%20m%24%5Cleq%24i%5C%3Ck%3A%20E%3Csub%3Ei%3C/sub%3E%29%20V%20E%3Csub%3Ek+1%3C/sub%3E%0A%3E%28***A***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%3D%20%24%5Cdaleth%24%28***E***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20%24%5Cdaleth%24E%3Csub%3Ei%3C/sub%3E%29%0A%3E%28***E***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%3D%20%28***N***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%24%5Cgeq%24%201%0A%3E%28***A***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%3D%20%28***N***%20i%3A%20m%24%5Cleq%24i%5C%3Cn%3A%20E%3Csub%3Ei%3C/sub%3E%29%20%3D%20n-m%0A%0A%23%23%232.%20%u4F55%u4E3Awp%uFF1F%5B%u539F%u4E66%u7B2C7%u7AE0%5D%0A%u539F%u4E66%u7684%u5B9A%u4E49%uFF1A%0A%3EThe%20Predicate%20Transformer%20wp%0A%3E%0A%3EThe%20set%20of%20all%20states%20such%20that%20execution%20of%20**S**%20begun%20in%20any%20one%20of%20them%20%3Cfont%20color%3D%22Blue%22%3Eis%20guaranteed%20to%20terminate%20in%20a%20finite%20amount%20of%20time%3C/font%3E%20in%20a%20state%20satisfying%20**R**.%0A%0Awp%u901A%u5E38%u88AB%u7528%u6765%u8868%u8FBE%u4E00%u6BB5%u7A0B%u5E8F%0A%24%24%5C%7BQ%5C%7DS%5C%7BR%5C%7D%24%24%0A%u6216%u8005%u8FD9%u6837%u5199%0A%24%24Q%5CRightarrow%20wp%28S%2CR%29%24%24%0A-%20Q%3A%u524D%u6761%u4EF6%20%20%0A-%20S%3A%u6267%u884C%u4EE3%u7801%uFF08%u539F%u6587%u79F0%u4E3Acommands%uFF09%20%20%0A-%20R%3A%u540E%u6761%u4EF6%0A%0A**wp%u7684%u7279%u6027**%0A%3E1%29%20wp%28S%2CF%29%20%3D%20F%20%20%20%0A%3E2%29%20wp%28S%20%5E%20Q%29%20%5E%20wp%28S%2CR%29%20%3D%20wp%28S%2CQ%20%5E%20R%20%29%20%20%0A%3E3%29%20if%20Q%20then%20wp%28S%2C%20Q%20%29%20%24%5CRightarrow%24%20wp%28S%2C%20R%29%20%20%20%0A%3E4%29%20wp%28S%20wp%28S%2C%20R%29%29%20%24%5CRightarrow%24%20wp%28S%20%2CQ%20v%20R%29%20%20%0A%3E5%29%20wp%28S%2C%20Q%29%20V%20wp%28S%2C%20R%29%20%3D%20wp%28S%2C%20Q%20V%20R%29%20%28for%20deterministic%20S%29%0A%0A%23%23%233.%20%u5FAA%u73AF%u68C0%u67E5%20%28%u539F%u4E66%u7B2C11%u7AE0%29%0A%u5B9A%u4E49%20%20%0A%24%24%20wp%28DO%2C%20R%29%20%5CRightarrow%20%28E%20k%3A%200%5Cleq%20k%3A%20H_k%28R%29%29%24%24%0A%0A%u7528%u6570%u5B66%u8BED%u8A00%u6807%u8BB0%u4E00%u4E2A%u5FAA%u73AF%u5982%u4E0B%3A%20%20%0A%7BQ%7D%20%20%0A%7Binv%20P%3A%20the%20invariant%7D%20%20%0A%7Bbound%20t%3A%20the%20bound%20function%7D%20%20%0A%7Binit%20IS%3A%20initialization%20command%7D%20%20%0A**do**%20*B*%3Csub%3E1%3C/sub%3E%20%24%5Crightarrow%24%20*S*%3Csub%3E1%3C/sub%3E%20%20%0A%20%24%5Csquare%5C%20%5Ccdots%24%20%20%0A%20%24%5Csquare%5C%20%24%20*B*%3Csub%3En%3C/sub%3E%20%24%5Crightarrow%24%20*S*%3Csub%3En%3C/sub%3E%20%20%20%0A**od**%0A%0A%23%23%23%23Invariant%0A%3E%3Cfont%20%20face%3D%22Arial%22%3EA%20predicate%20**P**%20that%20is%20true%20**before%20and%20after%20each%20iteration**%20of%20a%20loop.%3C/font%3E%20%20%0A%0A%u8FD9%u5C31%u662F%u8BF4P%u5728%u4EFB%u4F55%u60C5%u51B5%u4E0B%u90FD%u8981%u6210%u7ACB%uFF0C%u4E8E%u662F%u6709%20%20%0A-%20Q%20%24%5CRightarrow%24%20wp%28IS%2C%20P%29%20%20%0A-%20P%20%24%5CRightarrow%24%20wp%28DO%2C%20P%20%5E%20%24%5Cdaleth%24BB%29%0A%0A%23%23%23%23Bound%0A%u53C8%u53EBbound%20function%0A%3E%3Cfont%20%20face%3D%22Arial%22%3EThe%20function%20changes%20at%20each%20iteration%3B%20the%20relation%20remains%20invariantly%20true.%0A%3E**each%20iteration%20decreases%20t%20by%20at%20least%20one%uFF0Cso%20that%20termination%20is%20guaranteed%20to%20occur.**%3C/font%3E%0A%0A%u68C0%u67E5bound%u51FD%u6570%u786E%u4FDD%u5FAA%u73AF%u80FD%u7ED3%u675F%u3002%0A%0A%23%23%23%23Checklist%0A%3Cfont%20color%3D%22IndianRed%22%20size%3D%226%22%3E%u975E%u5E38%u91CD%u8981%21%21%21%3C/font%3E%20%20%0A%3Ca%20name%3D%22checklist%22%3E%3C/a%3E%20%0A1.%20Q%20%24%5CRightarrow%24%20wp%28IS%2C%20P%29%0A2.%20P%20%5E%20B%3Csub%3Ei%3C/sub%3E%20%24%5CRightarrow%24%20wp%28S%3Csub%3Ei%3C/sub%3E%2C%20P%29%0A3.%20P%20%5E%20%24%5Cdaleth%24**BB**%20%24%5CRightarrow%24%20R%0A4.%20P%20%5E%20**BB**%20%24%5CRightarrow%24%20%28t%20%3E%200%29%0A5.%20P%20%5E%20B%3Csub%3Ei%3C/sub%3E%20%24%5CRightarrow%24%20wp%28%22t%3Csub%3E1%3C/sub%3E%3A%3Dt%3B%20S%3Csub%3Ei%3C/sub%3E%22%2C%20%22t%20%3C%20t%3Csub%3E1%3C/sub%3E%22%29%20%20%0A%0A%u4F9D%u6B21%u9A8C%u8BC1%u8FD95%u6761%uFF0C%u5C31%u80FD%u8BC1%u660E%u4E00%u4E2A%u5FAA%u73AF%u7684%u6B63%u786E%u6027%u4E86%0A%0A%23%23%234.%20%u5982%u4F55%u8FD0%u7528%u6240%u6709%u7684%u77E5%u8BC6%u6765%u5F00%u53D1%u4E00%u6BB5%u7A0B%u5E8F%uFF08%u539F%u4E66PART%20III%uFF09%0A%23%23%23%23%u63A8%u6D4BCommand%0A%u901A%u8FC7%u540E%u6761%u4EF6R%uFF0C%u6765%u63A8%u6D4B%u6267%u884C%u4EE3%u7801%28Command%29%u3002%u8FD9%u5C31%u662F%u6240%u8C13%u7684Programming%20as%20a%20Goal-Oriented%20Activity%u3002%u8BE6%u60C5%u53C2%u770B%u539F%u4E66%u7B2C14%u7AE0%u3002%0A%3E**Strategy%20for%20developing%20an%20alternative%20command**%3A%20To%20invent%20a%20guarded%20command%uFF0Cfind%20a%20command%20C%20whose%20execution%20will%20establish%20postcondition%20R%20in%20at%20least%20some%20cases%3B%20find%20a%20Boolean%20B%20satisfying%20B%24%5CRightarrow%24wp%28C%2CR%29%20and%20put%20them%20together%20to%20form%20B%20%24%5Crightarrow%24C.%20Continue%20to%20invent%20guarded%20commands%20until%20the%20precondition%20of%20the%20construct%20implies%20that%20at%20least%20one%20guard%20is%20true.%20-%20%u539F%u6587%2814.7%29%0A%0A%23%23%23%23%u83B7%u5F97Guard%uFF08%u539F%u4E66%u7B2C15%u7AE0%uFF09%0A%u6240%u6709%u7684%u7F16%u7A0B%u90FD%u5E94%u8BE5%u662F%u7ED3%u679C%u5BFC%u5411%u7684%uFF08%u8FD9%u4E0E%u6D4B%u8BD5%u9A71%u52A8%u5F00%u53D1TDD%u7684%u601D%u60F3%u6697%u5408%uFF09%u3002%u6240%u4EE5%u540E%u6761%u4EF6R%u662F%u6700%u5148%u6709%u7684%u3002%0A%u5176%u6B21%uFF0C%u901A%u8FC7P%20%24%5Cwedge%5C%20%5Cdaleth%24**BB**%20%24%5CRightarrow%24%20R%u80FD%u5F97%u5230**BB**%uFF08%u5373guard%uFF09%u3002%u867D%u7136%u6709%u516C%u5F0FA%24%5CRightarrow%24B%20%3C%3D%3E%20%24%5Cdaleth%24A%20V%20B%3DT%uFF0C%u4F46%u662FB%u7684%u83B7%u5F97%u611F%u89C9%u66F4%u591A%u662F%u4F9D%u9760%u5206%u6790%u800C%u4E0D%u662F%u63A8%u5BFC%u3002%u5177%u4F53%u4F8B%u5B50%u4F1A%u5728%u672C%u6587%u6700%u540E%u63A8%u5BFCQuick%20Sort%u4E2D%u63D0%u53CA%u3002%0A%u5176%u4E2D%0A%24%24%20%5Cmathbf%20B%20%5Cmathbf%20B%20%3D%20B_1%20%5Cwedge%20%5C%20B%5C_2%20%5Cwedge%20%5Cldots%20%5C%20B%5C_n%24%24%0A%u4E0D%u8FC7%u7531%u4E0A%u5F0F%u53EF%u77E5%uFF0C%u6B64%u65F6%u7684guard%u8FD8%u662F%u4E2A%u603B%u7684guard%uFF0C%u8FD8%u9700%u8981%u5C06%u4E4B%u5206%u89E3%u4E3A%u5404%u4E2AB%3Csub%3Ei%3C/sub%3E%u3002%0A%23%23%23%23%u83B7%u5F97%u4E0D%u53D8%u91CFInvariant%uFF08%u539F%u4E66%u7B2C16%u7AE0%uFF09%0A%u4E66%u4E2D%u7ED9%u4E864%u79CD%u65B9%u6CD5%uFF1A%20%20%0A1.%20**Delete%20a%20conjunct.**%20For%20example%2C%20predicate%20A%20%5E%20B%20%5E%20C%20can%20be%20weakened%20to%20A%20%5E%20C%20%20%0A2.%20**Replace%20a%20constant%20by%20a%20variable.**%20For%20example%2C%20predicate%20x%20%24%5Cleq%24b%5B1%3A10%5D%2C%20where%20x%20is%20a%20simple%20variable%uFF0Ccan%20be%20weakened%20to%20x%20%24%5Cleq%24%20b%5B1%3Ai%5D%20%5E%201%24%5Cleq%20i%20%5Cleq%2410%uFF0Cwhere%20i%20is%20a%20fresh%20variable.%20Since%20a%20new%0Avariable%20has%20been%20introduced%2C%20%3Cfont%20color%3D%22IndianRed%22%3Eits%20possible%20set%20of%20values%20must%20be%20precisely%20stated.%3C/font%3E%20%20%0A3.%20**Enlarge%20the%20range%20of%20a%20variable.**%20For%20example%2C%20predicate%205%20%24%5Cleq%24%20i%20%3C%2010%20can%20be%20weakened%20to%200%20%24%5Cleq%24%20i%20%3C%2010.%20%20%0A4.%20**Add%20a%20disjunct.**%20For%20example%2C%20predicate%20A%20can%20be%20weakened%20to%20A%20v%20B%2C%20for%20some%20other%20predicate%20B.%0A%0A%u4E66%u4E2D%u63A8%u8350%u7528%u524D%u4E09%u4E2A%uFF0C%u6839%u636E%u9605%u8BFB%u672C%u4E66%u540E%u9762%u90E8%u5206%u7684%u7ECF%u9A8C%uFF0C%u6700%u5E38%u7528%u7684%u8FD8%u662F%u7B2C%u4E8C%u6761%u3002%0A%0A%23%23%u63A8%u5BFCQuick%20Sort%20%uFF08%u539F%u4E6618.2%u8282%uFF09%0A%u672C%u6587%u4EE5%u63A8%u5BFC%u5FEB%u901F%u6392%u5E8F%u4F5C%u4E3A%u7ED3%u675F%u3002%0A%u5FEB%u901F%u6392%u5E8F%u7684%u6838%u5FC3%u601D%u60F3%u5C31%u662F%u4E0D%u65AD%u5206%u5272%uFF0C%u5728%u5C0F%u6570%u7EC4%u4E2D%u9012%u5F52%u7684%u4F5C%u6392%u5E8F%uFF0C%u76F4%u5230%u5C0F%u6570%u7EC4%u7684%u5143%u7D20%u4E2A%u6570%u5C11%u4E8E%u6216%u7B49%u4E8E2%u4E2A%uFF0C%u5373%u53EF%u8FDB%u884C%u76F4%u63A5%u6392%u5E8F%u4E86%u3002%u6240%u4EE5%u5206%u6210Partition%u548CSort%u4E24%u90E8%u5206%u3002%0A%23%23%23Partition%20%uFF08%u539F%u4E66%u7EC3%u4E6016.5%uFF09%0A%u4E00%u6B21%u5206%u5272%u7684%u540E%u6761%u4EF6%u5982%u4E0B%0AR%3A%20%24m%5Cleq%20p%3Cn%20%5Cwedge%20perm%28b%2C%20B%29%20%5Cwedge%20b%24%21%5BAlt%20text%5D%28./1453770826140.png%29%0A%23%23%23%23%u7531R%u83B7%u5F97P%0A%u901A%u8FC7%u4E0A%u4E00%u8282%u4E2D%u7684%u65B9%u6CD5%u4E8C**Replace%20a%20constant%20by%20a%20variable.**%u6765%u5F97%u5230P%u3002%0AP%3A%20%24m%3Cq%20%5Cleq%20p+1%20%5Cleq%20n%20%5Cwedge%20x%3DB%5Bm%5D%20%5Cwedge%20%24%21%5BAlt%20text%5D%28./1453770875251.png%29%0A%23%23%23%23%u7531P%20%24%5Cwedge%20%5Cdaleth%24**BB**%20%24%5CRightarrow%24R%3Cfont%20color%3D%22IndianRed%22%3E%u63A8%u7B97%3C/font%3EBB%0A%u6CE8%u610F%u662F%u63A8%u7B97%uFF0C%u4E0D%u662F%u4E25%u683C%u7684%u903B%u8F91%u63A8%u5BFC%0A%24%5Cbecause%5C%20%24P%20%24%5Cwedge%24%20%28p-q+1%3D0%29%20%24%5CLeftrightarrow%24%20R%0A%24%5Ctherefore%5C%20%5Cdaleth%24**BB**%20%3D%20%28p-q+1%3D0%29%0A%24%5Ctherefore%5C%20%24**BB**%20%3D%20%28p%24%5Cneq%24q-1%29%0A%23%23%23%23Bound%20function%0At%20%3D%20p-q+1%0A%23%23%23%23%u63A8%u6D4Bcommand%0A%u7531QuickSort%u7684%u57FA%u672C%u7B97%u6CD5%u53EF%u77E5%uFF0C%u6709%u4E09%u4E2A%u53EF%u80FD%u7684command%0A1.%20q++%0A2.%20p--%0A3.%20swap%28b%5Bp%5D%2C%20b%5Bq%5D%29%0A%u6240%u4EE5%u73B0%u5728%u7A0B%u5E8F%u5F62%u5F0F%u5982%u4E0B%uFF1A%0Ado%20p%24%5Cneq%24q-1%0A%u3000if________%20%24%5Crightarrow%24%20p%3A%3Dp-1%0A%u3000%24%5Csquare%24%20________%20%24%5Crightarrow%24%20q%3A%3Dq+1%0A%u3000%24%5Csquare%24%20________%20%24%5Crightarrow%24%20swap%28b%5Bp%5D%2C%20b%5Bq%5D%29%0A%u3000fi%0Aod%0A%23%23%23%23%u7531command+P+BB%u83B7%u5F97Guard%0AP%24%5Cwedge%24**BB**%24%5Cwedge%20B_i%20%5CRightarrow%24wp%28S%2CP%29%0A1.%20S%20%3D%20%22p%3A%3Dp-1%22%0A%u3000%u3000wp%28S%2CP%29%20%3D%20%24%28m%3Cq%20%5Cleq%20p%20%5Cleq%20n%29%20%5Cwedge%20%28x%3DB%5Bm%5D%29%20%5Cwedge%20%24%21%5BAlt%20text%5D%28./1453770917851.png%29%0A%24%5Cbecause%24**BB**%20%3D%20%28p%24%5Cneq%24q-1%29%0A%24%5Ctherefore%24q%5C%3Cp+1%0A%24%5Ctherefore%24q%24%5Cleq%24p%0A%u53EF%u89C1%uFF0C%u8981%u8BC1%u51FAP%24%5Cwedge%24**BB**%24%5Cwedge%20B_i%20%5CRightarrow%24wp%28S%2CP%29%u53EA%u8981%u56FE%u5F62%u4E2D%u7684b%5Bp%5D%u80FD%u6EE1%u8DB3%u5206%u5272%u6761%u4EF6%u5C31%u53EF%u4EE5%u4E86%uFF0C%u6240%u4EE5%u6709%0A%24%24B_i%20%3D%20b%5Bp%5D%3Ex%24%24%0A2.%20S%20%3D%20%22q%3A%3Dq+1%22%0A%u8FC7%u7A0B%u7C7B%u4F3C%0A%u3000%u3000wp%28S%2CP%29%3D%24m%3Cq+1%5Cleq%20p+1%20%5Cleq%20n%20%5Cwedge%24%21%5BAlt%20text%5D%28./1453770962336.png%29%0A%0A%u5BF9%u4E8E%u524D%u534A%u90E8%u5206%u7684%u8BC1%u660E%u5982%u4E0B%uFF1A%0AP%u4E2D%u6709%24m%3Cq%20%5Cleq%20p+1%20%5Cleq%20n%24%0A**BB**%20%3D%20%28p%24%5Cneq%24q-1%29%0A%24%5Ctherefore%24%20q%20%3C%20p%20%24%5CLeftrightarrow%24%20q%20%24%5Cleq%24p-1%20%24%5CLeftrightarrow%24%20q+1%24%5Cleq%24p%0A%u5F97%u8BC1%0A%u5BF9%u4E8E%u540E%u534A%u90E8%u5206%uFF0C%u663E%u800C%u6613%u89C1%u9700%u8981b%5Bq%5D%24%5Cleq%24x%2C%u5373%0A%24%24B_i%20%3D%20%28b%5Bq%5D%20%5Cleq%20x%29%24%24%0A3.%20swap%28b%5Bp%5D%2C%20b%5Bq%5D%29%0A%u3000%u3000wp%28S%2CP%29%3D%24m%3Cq%20%5Cleq%20p+1%20%5Cleq%20n%20%5Cwedge%24%21%5BAlt%20text%5D%28./1453771153446.png%29%0A%u4ECD%u7136%u663E%u800C%u6613%u89C1%u6709%uFF1A%0A%24%24B_i%20%3D%20b%5Bq%5D%20%5Cleq%20x%20%5Cwedge%20b%5Bp%5D%3Ex%24%24%0A%u4F9D%u6B21%3Cfont%20color%3D%22IndianRed%22%20size%3D%225%22%3E%u5206%u5272%u7A0B%u5E8F%3C/font%3E%u5199%u4F5C%uFF1A%0A**do**%20p%24%5Cneq%24q-1%0A%u3000**if**%20b%5Bp%5D%5C%3Ex%20%24%5Crightarrow%24%20p%3A%3Dp-1%0A%u3000%24%5Csquare%24%20b%5Bq%5D%24%5Cleq%24%20x%20%24%5Crightarrow%24%20q%3A%3Dq+1%0A%u3000%24%5Csquare%24%20%28b%5Bq%5D%24%5Cleq%24%20x%29%20%24%5Cwedge%24%20%28b%5Bp%5D%5C%3Ex%29%24%5Crightarrow%24%20swap%28b%5Bp%5D%2C%20b%5Bq%5D%29%3B%20p%2Cq%3A%3Dp-1%2Cq+1%0A%u3000**fi**%0A**od**%0A%23%23%23%23%u9A8C%u8BC1%0AQ%3A%20T%0AR%3A%20%24m%5Cleq%20p%20%5Cleq%20n%20%5Cwedge%20perm%28b%2C%20B%29%20%5Cwedge%20b%24%21%5BAlt%20text%5D%28./1453771195972.png%29%0AP%3A%20%24m%3Cq%20%5Cleq%20p+1%20%5Cleq%20n%20%5Cwedge%20x%3DB%5Bm%5D%20%5Cwedge%20%24%21%5BAlt%20text%5D%28./1453771223774.png%29%0ABound%3A%20t%20%3D%20p-q+1%0AIS%3A%20p%3A%3Dn-1%2C%20q%3A%3Dm+1%0A%u6839%u636E5%u6761%5BCheck%20List%5D%28%23checklist%29%uFF0C%u4F9D%u6B21check%uFF1A%0A1.%20wp%28IS%2C%20P%29%20%3D%20%24m%3Cm+1%5Cleq%20n%20%5Cwedge%20%28x%3DB%5Bm%5D%29%20%5Cwedge%20%24%21%5BAlt%20text%5D%28./1453771263078.png%29%0A%u663E%u7136%u662F%u6210%u7ACB%u7684%0A2.%20P%24%5Cwedge%24**BB**%24%5Cwedge%20B_i%20%5CRightarrow%24%20wp%28%24S_i%24%2CP%29%0A%u8FD9%u4E2A%u663E%u7136%u4E5F%u662F%u6210%u7ACB%u7684%uFF0C%u56E0%u4E3A%u6211%u4EEC%u7684%24B_i%24%u5C31%u662F%u8FD9%u4E48%u6765%u7684%0A3.%20P%24%5Cwedge%20%5Cdaleth%24**BB**%24%5CRightarrow%24R%0A%u540C%u4E0A%uFF0C%u4EA6%u6210%u7ACB%0A4.%20P%24%5Cwedge%24**BB**%24%5CRightarrow%24%28t%5C%3E0%29%0A**BB**%20%3D%20%28p%24%5Cneq%24q-1%29%20%24%5CLeftrightarrow%24%20p-q+1%24%5Cneq%240%0A%u53C8%u7531P%u6709%0Aq%24%5Cleq%24p+1%20%24%5CLeftrightarrow%24%20p-q+1%24%5Cgeq%240%0A%24%5Ctherefore%24%20t%3Dp-q+1%3E0%0A%u5F97%u8BC1%0A5.%20P%24%5Cwedge%20B_i%20%5CRightarrow%24%20wp%28%22%24t_1%3Dt%3BS_i%24%22%2C%20%22t%3Ct1%22%29%0A%u5BF9%u4E8E%u4E09%u79CD%24S_i%24%2Ct%u90FD%u663E%u7136%u4F1A%u53D8%u5C0F%uFF0C%u6240%u4EE5%u6EE1%u8DB3%0A%0A%u7EFC%u4E0A%uFF0C5%u6761check%20point%u90FD%u6EE1%u8DB3%uFF0C%u7A0B%u5E8F%u6B63%u786E%u6027%u53EF%u4FDD%u8BC1%0A%23%23%23Sort%0A%23%23%23%23%u63A8%u5BFC%0A%u6839%u636E%u5FEB%u901F%u6392%u5E8F%u7B97%u6CD5%u53EF%u77E5%uFF0C%u5BF9%u6570%u7EC4%u6392%u5E8F%uFF0C%u5373%u8FDB%u884C%u82E5%u5E72%u6B21%u5206%u5272%uFF0C%u76F4%u81F3%u5B50%u533A%u95F4%u5305%u542B%24%5Cleq%242%u4E2A%u5143%u7D20%uFF0C%u5373%u53EF%u4EE5%u8FDB%u884C%u76F4%u63A5%u6392%u5E8F%u3002%0A*%20P%3A%20*s*%20is%20a%20set%20of%20pairs%20%28i%2C%20j%29%20representing%20disjoint%20array%20sections%20b%5Bi%3Aj%5D%20of%20b.%20Further%uFF0Cb%5B0%3An%u20141%5D%20is%20ordered%20iff%20all%20the%20disjoint%20partitions%20given%20by%20set%20*s*%20are.%0A*%20IS%3A%20*s*%3A%3D%7B%280%2Cn-1%29%7D%0A*%20R%3A%20b%5B0%3An-1%5D%20are%20ordered%0A*%20t%3A%20n%20-%20ordered%0A%0A%u5FEB%u901F%u6392%u5E8F%u7A0B%u5E8F%u5982%u4E0B%3A%0A*s*%3A%3D%7B%280%2Cn-1%29%7D%0A%7B*Invariant*%3A%20%u5982%u4E0AP%7D%0A**do**%20*s*%24%5Cneq%24%7B%7D%20%24%5Crightarrow%24%20Choose%28%28i%2Cj%29%2C*s*%29%3B%20s%3A%3Ds-%7B%28i%2Cj%29%7D%3B%0A%u3000%u3000%u3000**if**%20j-i%20%5C%3C%202%20%24%5Crightarrow%24%20Sort%20b%5Bi%3Aj%5D%20directly%0A%u3000%u3000%u3000%24%5Csquare%24%20j-i%20%24%5Cgeq%242%20%24%5Crightarrow%24%20Partition%28b%2Ci%2Cj%2Cp%3B%29%3B%20%24s%3A%3Ds%5Ccup%20%7B%28i%2Cp-1%29%7D%20%5Ccup%20%7B%28p+1%2Cj%29%7D%24%0A%u3000%u3000%u3000**fi**%0A**od**%0A%23%23%23%23C%u4EE3%u7801%0A%u6700%u7EC8Quick%20Sort%20C%u4EE3%u7801%u5B9E%u73B0%u5982%u4E0B%3A%0A%60%60%60c%0A%23define%20N%09%09%0950%0A%23define%20MAX_SPLIT%20%0950%20//%20This%20should%20be%20logN%0Avoid%20swap%28int*%20b%2C%20int%20p%2C%20int%20q%29%0A%7B%0A%09b%5Bp%5D%3Db%5Bp%5D+b%5Bq%5D%3B%0A%09b%5Bq%5D%3Db%5Bp%5D-b%5Bq%5D%3B%0A%09b%5Bp%5D%3Db%5Bp%5D-b%5Bq%5D%3B%0A%7D%0Aint%20Partition%20%28int*%20b%2C%20int%20m%2C%20int%20n%29%0A%7B%0A%09assert%28n%3Em%29%3B%0A%09int%20p%3Dn-1%2C%20q%3Dm+1%3B%0A%09while%20%28p%20%21%3D%20q-1%29%0A%09%7B%0A%09%09if%20%28b%5Bp%5D%3Ex%29%0A%09%09%7B%0A%09%09%09p--%3B%0A%09%09%7D%0A%09%09else%20if%20%28b%5Bq%5D%3C%3Dx%29%0A%09%09%7B%0A%09%09%09q++%3B%0A%09%09%7D%0A%09%09else%20if%20%28b%5Bq%5D%3C%3Dx%20%26%26%20b%5Bp%5D%3Ex%29%0A%09%09%7B%0A%09%09%09swap%28b%2C%20p%20%2Cq%29%3B%0A%09%09%09p--%3B%0A%09%09%09q++%3B%0A%09%09%7D%0A%09%7D%0A%09return%20p%3B%0A%7D%0Avoid%20QuickSort%28int*%20b%2C%20int%20n%29%0A%7B%0A%09typedef%20struct%20%0A%09%7B%0A%09%09int%20start%3B%0A%09%09int%20end%3B%0A%09%7DPair%20s%5BMAX_SPLIT%5D%20%3D%20%7B0%7D%3B%0A%09int%20count%20%3D%201%3B%20//%20how%20many%20pairs%20in%20s%0A%09s%5B0%5D.start%20%3D%200%3B%0A%09s%5B0%5D.end%20%3D%20n-1%3B%0A%09while%20%28count%20%3E%200%29%0A%09%7B%0A%09%09Pair%20p%3B%0A%09%09memcpy%28%26p%2C%20%26s%5Bcount-1%5D%2C%20sizeof%28Pair%29%29%3B%0A%09%09if%28p.end%20-%20p.start%20%3C%202%29%0A%09%09%7B%0A%09%09%09if%20%28p.start%20%3E%20p.end%29%0A%09%09%09%7B%0A%09%09%09%09swap%20%28b%2C%20p.start%2C%20p.end%29%3B%0A%09%09%09%09count%20--%3B%0A%09%09%09%7D%0A%09%09%09else%0A%09%09%09%7B%0A%09%09%09%09int%20m%20%3D%20p.start%3B%0A%09%09%09%09int%20n%20%3D%20p.end%20-%20p.start%20+%201%3B%0A%09%09%09%09int%20x%20%3D%20Partition%28b%2C%20m%2C%20n%29%3B%0A%09%09%09%09s%5Bcount-1%5D.start%20%3D%20p.start%3B%0A%09%09%09%09s%5Bcount-1%5D.end%20%3D%20x-1%3B%0A%09%09%09%09s%5Bcount%5D.start%20%3D%20x+1%3B%0A%09%09%09%09s%5Bcount%5D.end%20%3D%20p.end%3B%0A%09%09%09%09count%20++%3B%0A%09%09%09%7D%0A%09%09%7D%20%0A%09%7D%0A%7D%0A%60%60%60%0A%0A%0A%0A%0A%0A%0A