在这里插入代码片
前言:最近正在学习python的一些排序算法实现,在对算法的流程理解后,使用递归完成了快速排序,以下是完整的思路,代码可能不是最完美的,希望能对大家有所帮助。
现对列表 h 排序
h = [9,1,6,3,8,0,12,9]
排序的目的,在于将列表中的每个值放在正确的顺序位置上,
递归实现快速排序原理:
第一步:设定需要排序的列表首项作为目标数据,通过搜索和交换,将比目标数据小的数据交换到目标数据前面,比目标数据大或者相等的数据交换到目标数据后边,
第二步:将目标数据之前的部分和目标数据后边的部分递归进行,直到所有的数据都排好顺序。
详解:
第一步:
target = h[0] # 目标数据
按照第一步的目标 :将比目标数据小的数据交换到目标数据前面,比目标数据大或者相等的数据交换到目标数据后边,在不使用其他第三个中间变量的情况下。我们使用交换列表元素的方式完成。
基本思路是:先从列表的右边开始一个一个和目标数据比较,如果遇到比目标数据小的值,就停下来,换从列表的左边一个一个和目标数据比较,如果遇到了大于等于目标数据的值,就将之前找到的较小数和目前的较大数交换位置。
首先用两个变量存储两个搜索方向的下标。
start_index = 0
end_index = len(h) - 1
接下来从后往前搜索比目标值小的值。设定完成循环的条件除了小于目标值还要大于左边的索引值,最后的下标为end_index的值便为比目标值小的值。
while lst[end_index] >= lst[target] and start_index < end_index:
end_index -= 1
在上述循环停下来之后,就开始从前往后搜索。最后下标为 start_index 的值便为大于等于目标数的值。
while lst[start_index] < lst[target] and start_index < end_index:
start_index += 1
上面的循环也结束后,交换较小目标值和较大的目标值。
lst[start_index], lst[end_index] = lst[end_index], lst[start_index]
上述所有的步骤完成后,就完成了第一步交换,然后循环进行。start_index 和 end_index 也不断接近,直到 两个值相等,停止。
while start_index < end_index:
while lst[end_index] >= lst[target] and start_index < end_index:
end_index -= 1
while lst[start_index] < lst[target] and start_index < end_index:
start_index += 1
lst[start_index], lst[end_index] = lst[end_index], lst[start_index]
以上循环完成后,start_index = end_index = 目标值应该在的位置,所以,将此位置和目标值交换。
lst[end_index], lst[target] = lst[target], lst[end_index]
到目前位置,第一大步才完整结束。完成了对目标值“排序”的小目标。
第二步:
这一部分,如果对于递归算法不了解,建议先去了解一下递归算法。再继续查看以下内容。
为了使用递归算法,我们现在对以上代码做一个封装.
def quick_sort(lst, target, start_index, end_index):
while start_index < end_index:
while lst[end_index] >= lst[target] and start_index < end_index:
end_index -= 1
while lst[start_index] < lst[target] and start_index < end_index:
start_index += 1
lst[start_index], lst[end_index] = lst[end_index], lst[start_index]
lst[end_index], lst[target] = lst[target], lst[end_index]
# 在这里将要实现目标值后半部分第一个值的"排序"
# 在这里将要实现目标值前半部分第一个值的"排序"
调用quick_sort函数实现目标值后半部分第一个值的排序过程中,我们只需要确定几个参数即可,
lst : lst
target:上一次找到的目标值的下一位,即 start_index +1。
start_index :也是上一次找到的目标值的下一位,即 start_index +1。
end_index : 每一次的最后元素的下标,是上一次排序最后元素的下标。
因为在排序的过程中end_index和start_index 已经发生了变化,所以,选择在排序之前使用另两个变量做一个存储如下:
last_end_index = end_index
lat_start_index = start_index
调用quick_sort 完成目标值后半部分第一个值的"排序"
quick_sort(lst, start_index+1, start_index+1, last_end_index)
同理完成目标值前半部分第一个值的"排序"
quick_sort(lst, lat_start_index+1, lat_start_index+1, start_index-1)
最后不要忘记写递归的停止条件 end_index > start_index
至此,我们完成了递归实现快速排序。
全部代码如下,本人菜鸟新手,感谢各位斧正指导。
def quick_sort(lst, target, start_index, end_index):
last_end_index = end_index # 存储开始和结束的索引
lat_start_index = start_index
if end_index > start_index: # 停止递归的条件
while start_index < end_index:
# 从右向左搜索
while lst[end_index] >= lst[target] and start_index < end_index:
end_index -= 1
# 从左向右搜索
while lst[start_index] < lst[target] and start_index < end_index:
start_index += 1
lst[start_index], lst[end_index] = lst[end_index], lst[start_index] # 交换较大值和较小值
lst[end_index], lst[target] = lst[target], lst[end_index] # 交换中心点和基准点的值
quick_sort(lst, start_index+1, start_index+1, last_end_index) # 排右半部分的顺序
quick_sort(lst, lat_start_index+1, lat_start_index+1, start_index-1) # 排左半部分的顺序
if __name__ == "__main__":
h = [9,1,6,3,8,0,12,9]
quick_sort(h, 0, 0, len(h)-1)
print(lst)