边界问题:
边界问题涉及到一种特殊情况:由于偶数个元素时的中心Center / 2总是向下取整,所以我们会产生左右边界是否应该包含该中心Center的问题。
1.左部分右边界包含Center:
- 出口情况:
在这种情况下,当元素个数N为2时,如
{1, 2}
,Left = 0;Center = 0,Right = Center = 0;- 此时,如果遍历出口已经存在Left == Right,则无需考虑Left > Right的情况,它是永远都不会出现的。
如果遍历出口不存在Left == Right,则还必须考虑Left > Right的情况。因为该情况会在Left == Right时的下一次遍历出现。
- 遍历情况:
-
2.左部分右边界不包含Center:
- 出口情况:
在这种情况下,当元素个数N为2时,如
{1, 2}
,Left = 0;Center = 0,Right = Center - 1 = -1;- 此时,如果遍历出口已经存在Left == Right,则还必须考虑Left > Right的情况。该情况在N=2时一定会出现。
如果遍历出口不存在Left == Right,则还必须考虑Left > Right的情况。因为该情况会在Left == Right时的下一次遍历出现。
- 遍历情况:
在这种情况下的遍历默认不会包含Center元素,除非在每一次遍历过程中都对Center索引位的值进行了相关操作。
3.右部分左边界包含Center:
由于Center向下取整,当元素个数N=2时,如
{1, 2}
,Left = Center = 0;Right = 1;- 此时,其左边界将无限制地为0,右边界也无限制地为1,从而造成死循环。故谈论右部分左边界包含Center值的行为是无意义的。
总结:
- 结合上面的结论可以使我们在使用左边界索引、中心索引、右边界索引时规避数组越界的问题:
- 当我们放任左边界Left > 右边界Right时,就很有可能造成数组的越界。因此:
- 当我们包含Center且具有Left == Right的出口条件时,我们就可以不必考虑数组越界的问题;
- 其余情况,我们都需要考虑Left > Right时可能造成的数组越界问题。
- 当我们需要先对根操作然后再递归时,为了避免重复,就可以选择用不包含Center的写法;
- 当我们不需要先对根进行操作时,就可以选择包含Center的写法,因为最后总会分治到根上,即在右侧分治时Left==Right的时候。
- 当我们放任左边界Left > 右边界Right时,就很有可能造成数组的越界。因此: