我从quicksort的基本框架出发,得出了一个比较好理解的代码:
最后之所有有分支比较,是因为我发现,a[l]是否大于mid是未知的;比较好理解, 但是有的dirty.
查书上的c代码, 用Python写出代码2:
如果改成代码3, 变化仅仅是加上一个条件 l<r,就会出错:
代码2的微妙之处在于while退出时候保证有 a[r] <= mid, 形式上这是由 while a[r] > mid 保障的;而代码3再加上一个条件,破坏了这一个保证。
ps: 有些复杂的算法,不可能一步想到位,有些微妙的地方恐怕还是要通过try-fail来收敛吧.
- def qsort_2( a, s, t ):
- if t - s <= 0:
- return
- mid = a[s]
- l = s
- r = t
- #print a[s:t+1],
- while 1:
- while a[l] < mid and l < r:
- l += 1
- while a[r] > mid and l < r:
- r -= 1
- if l < r:
- a[l], a[r] = a[r], a[l]
- l += 1
- r -= 1
- else:
- break
- if a[l] > mid:
- qsort_2( a, s, l-1 )
- qsort_2( a, l, t )
- elif a[l] < mid:
- qsort_2( a, s, l )
- qsort_2( a, l+1, t )
- else:
- qsort_2( a, s, l-1 )
- qsort_2( a, l+1, t )
查书上的c代码, 用Python写出代码2:
- def qsort_3( a, s, t ):
- if t - s <= 0:
- return
- mid = a[s]
- l = s + 1
- r = t
- #print a[s:t+1],
- while 1:
- while a[l] < mid and l < r:
- l += 1
- while a[r] > mid:
- r -= 1
- if l < r:
- a[l], a[r] = a[r], a[l]
- l += 1
- r -= 1
- else:
- break
- #print 'mid = ', mid, 'a[r] =', a[r], 'a[l] =', a[l],a[s:t+1]
- a[s], a[r] = a[r], a[s]
- qsort_3( a, s, r-1 )
- qsort_3( a, r+1, t )
如果改成代码3, 变化仅仅是加上一个条件 l<r,就会出错:
- def qsort_3( a, s, t ):
- if t - s <= 0:
- return
- mid = a[s]
- l = s + 1
- r = t
- #print a[s:t+1],
- while 1:
- while a[l] < mid and l < r:
- l += 1
- while a[r] > mid and l < r:
- r -= 1
- if l < r:
- a[l], a[r] = a[r], a[l]
- l += 1
- r -= 1
- else:
- break
- #print 'mid = ', mid, 'a[r] =', a[r], 'a[l] =', a[l],a[s:t+1]
- a[s], a[r] = a[r], a[s]
- qsort_3( a, s, r-1 )
- qsort_3( a, r+1, t )
ps: 有些复杂的算法,不可能一步想到位,有些微妙的地方恐怕还是要通过try-fail来收敛吧.