分区
此处的分区指的是从数组随机选取一个值,以其为轴,将比它小的值放到它左边,比它大的值放到它右边。分区的算法实现起来很简单,例子如下所示。假设有一个下面这样的数组。
从技术上来说,选任意值为轴都可以,我们就以数组最右的值为轴吧。现在轴就是3了,我们把它圈起来。
然后放置指针,它们应该分别指向排除轴元素的数组最左和最右的元素。
接着就可以分区了,步骤如下。
(1) 左指针逐个格子向右移动,当遇到大于或等于轴的值时,就停下来。
(2) 右指针逐个格子向左移动,当遇到小于或等于轴的值时,就停下来。
(3) 将两指针所指的值交换位置。
(4) 重复上述步骤,直至两指针重合,或左指针移到右指针的右边。
(5) 将轴与左指针所指的值交换位置。
当分区完成时,在轴左侧的那些值肯定比轴要小,在轴右侧的那些值肯定比轴要大。因此,轴的位置也就确定了,虽然其他值的位置还没有完全确定。
让我们来把此流程套到示例数组上。第1步:拿左指针(正指向0)与轴(值为3)比较。
由于0比轴小,左指针可以右移。
第2步:右移左指针。[插图]将左指针(值为5)与轴比较。它比轴小吗?不。于是左指针停在这里,下一步我们启动右指针。
第3步:比较右指针(值为6)和轴。它比轴大吗?对。于是右指针左移。
第4步:左移右指针。
比较右指针(值为1)和轴。它比轴大吗?不。于是右指针停下。
第5步:因为两个指针都停住了,所以交换它们的值。
随后,再次启动左指针。
第6步:右移左指针。
比较左指针(值为2)和轴。它比轴小吗?对。于是继续右移。
第7步:左指针移到下一格子。注意,这时两个指针都指向同一个值了。
比较左指针和轴。由于左指针的值比轴要大,我们将其停在那里。而且现在左指针与右指针重合,无须再移动指针了。
第8步:到了分区的最后一步,将左指针的值与轴交换位置。
虽然数组还没完全排好序,但我们已完成了一次分区。即比轴(值为3)小的值都聚在了它的左侧,比轴大的值都聚在了它的右侧,这就意味着3已经被放置到正确的位置上了。