do while的python实现:
第一种方法(适合func()较短的情况):
func()
while condition:
func()
第二种方法(适合func()较长的情况):
while True:
func()
if not condition:
break
Python代码
def quicksort(q, l, r):
# 退出递归条件:
if l >= r:
return
# 1. 确定分界点
x = q[(l + r) // 2]
# 2. 调整区间
# 比较优雅的方式:两个指针
i, j = l - 1, r + 1
while i < j:
while True:
i += 1
if q[i] >= x:
break
while True:
j -= 1
if q[j] <= x:
break
if i < j:
# 这里的if语句可以过滤掉前面两个while出来时i>=j的情况(这种情况下q[i]和q[j]就不应该交换了)
q[i], q[j] = q[j], q[i]
# 3. 递归处理左右两段
quicksort(q, l, j)
quicksort(q, j + 1, r)
if __name__ == "__main__":
n = int(input())
q = list(map(int, input().split()))
quicksort(q, 0, n - 1)
print(' '.join(str(e) for e in q))
以下是个人的一点见解,如有错误欢迎指出~
在写题解的时候发现有人问为什么上面的调整区间部分不能写成:
i, j = l, r
while i < j:
while q[i] < x:
i += 1
while q[j] > x:
j -= 1
if i < j:
q[i], q[j] = q[j], q[i]
我认为这是因为这样写的话,如果当内层两个while循环结束后满足i < j
,且q[i] == q[j] == x
,那么就等于没有交换,并且下一次外层循环时两个while循环就都不会执行了,因此i和j的值就永远不会改变了,进而进入死循环。数组中只要有重复元素应该就会触发此种情况。
因此为了避免进入死循环,可以将内层的两个while循环改成do while的形式,这样就保证了即使满足i < j
和q[i] == q[j] == x
时内层两个循环依然能执行一次以改变i和j的值。但是此时就要更改初始值为i, j = l - 1, r + 1
,以免在最外层第一次循环时跳过q[l]
和q[r]
。这样改过以后就是上面的AC代码了。