1.快速排序的思想基于分治法,取列表中第一个元素作为基准元素赋予一个变量(mid),然后取两个变量(low, high)用来记录列表最左边和最右边的下标。
def quick_sort(list1, first, last):
mid = list1[first]
low = first
high = last
2.(顾名思义,我们希望high对应的元素应该大于基准元素) 所以让high开始左移,没遇到小于基准元素的情况就让high一直左移。如果找到high对应的元素小于基准元素mid时,跳出high的遍历。并且让high的元素赋在low的位置上,(保证了high右边都大于基准,low左边都小于基准)此时high的左移行为停止,开始让low右移。
while (low < high) and list1[high] >= mid:
high -= 1
'''跳出循环,说明遍历到了小于基准的元素或者两下标相遇了'''
list1[low] = list1[high] #将high对应的值赋在low的位置
3.(同理,我们应该让low对应的元素都小于基准元素) 替换完了以后,就应该让low开始右移,没遇到大于基准元素的情况就让low一直右移,如果low遍历到大于基准元素,跳出low的遍历,并且让low对应的元素赋在high的位置上,(保证了high右边都大于基准,low左边都小于基准)此时low的右移行为停止。
while (low < high) and list1[low] < mid:
low += 1
'''跳出循环,说明遍历到了大于基准的元素或者两下标相遇了'''
list1[high] = list1[low] #此时应该把low对应值赋给high的位置
4.low和high的遍历都跳出后,应该继续回到low和high的遍历中,直至low和high相遇,此时,把基准元素赋在low和high的相遇位置上。
while low != high:
while (low < high) and list1[high] >= mid:
high -= 1
list1[low] = list1[high]
while (low < high) and list1[low] < mid:
low += 1
list1[high] = list1[low]
'''跳出整个循环说明,low和high已经相遇'''
list1[low] = mid #把基准元素放到正确位置
这样就把基准元素成功按从小到大的顺序直接插到了列表中正确的位置。那么往后从基准元素把列表分成两个子列表,接着同样的逻辑继续给两个子列表做快速排序,然后一直子列表再继续分,以此类推。同样的逻辑操作,所以我们用到了递归思想,那么递归开始返回的地方是排序函数输入的头(first)和尾(last)相等时就返回(即子列表中只有一个元素了)
def quick_sort(list1, first, last):
if first >= last: #最后满足该条件就递归返回
return list1
mid = list1[first] #基准元素
low = first
high = last
while low != high:
'''high开始左移'''
while (low < high) and list1[high] >= mid:
high -= 1
list1[low] = list1[high]
'''low开始右移'''
while (low < high) and list1[low] < mid:
low += 1
'''两个下标相遇时,开始插入基准元素'''
list1[high] = list1[low]
list1[low] = mid
quick_sort(list1, first, low-1)
quick_sort(list1, low+1, last)
return list1 #递归出口,没有这个出口的话,最后会返回None
测试代码:
a = [random.randint(0,100) for i in range (10)]
print(a)
b = quick_sort(a,0,len(a)-1)
print(b)
返回值:
F:\测试>python -u "f:\测试\快速排序.py"
[99, 53, 49, 89, 49, 69, 31, 32, 20, 49]
[20, 31, 32, 49, 49, 49, 53, 69, 89, 99]
注!:递归出口和返回条件是关键,没有返回条件就会无限递归,没有出口函数就不会返回任何值,所以要在这两个地方仔细思考。