原题如下:
给定你一个长度为 n 的整数数列。请你使用快速排序对这个数列按照从小到大进行排序。并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼10^9 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
1. 整体功能概述
快速排序思想:
代码来源
作者:Philosober
链接:https://www.acwing.com/activity/content/code/content/902188/
def quick_sort(l,r,data):if l >= r:returni = l - 1j = r + 1pivot = data[(i+j) // 2]while i < j:while 1:i += 1if data[i] >= pivot:breakwhile 1:j -= 1if data[j] <= pivot:breakif i < j:data[i],data[j] = data[j],data[i]quick_sort(l,j,data)quick_sort(j+1,r,data)def main():l = 0r = n-1quick_sort(l,r,data)if __name__ == "__main__":n = int(input())data = [int(x) for x in input().split()]main()print(' '.join(list(map(str, data))))
结果输出:
这段代码实现了快速排序算法,用于对输入的一组整数进行排序,并在排序完成后输出排序后的结果。快速排序是一种高效的排序算法,它基于分治策略,通过选择一个 “枢轴”(pivot)元素,将数组分为两部分,左边部分的元素都小于等于枢轴,右边部分的元素都大于等于枢轴,然后递归地对这两部分进行排序。
2. 函数和模块结构
quick_sort
函数:这是实现快速排序核心逻辑的函数,它接受三个参数:l
(表示要排序的数组片段的左边界索引)、r
(表示要排序的数组片段的右边界索引)和data
(表示要排序的整数数组)。main
函数:主要用于设置排序的初始边界,并调用quick_sort
函数进行排序。- 在
if __name__ == "__main__"
语句块中,获取用户输入的数组长度n
和数组元素,然后调用main
函数完成排序并输出结果。
3. quick_sort
函数详细解释
(1)递归终止条件
if l >= r:return
当要排序的数组片段的左边界索引l
大于等于右边界索引r
时,说明该片段已经只有一个元素或者为空,此时不需要再进行排序,直接返回即可。
(2)初始化指针和选择枢轴
i = l - 1
j = r + 1
pivot = data[(i + j) // 2]
- 首先,初始化两个指针
i
和j
,i
初始化为左边界索引l
减 1,j
初始化为右边界索引r
加 1。这里的初始化值是为了后续在循环中能正确地向中间移动指针并找到合适的元素与枢轴进行比较。 - 然后,选择枢轴元素。这里通过
data[(i + j) // 2]
来选择枢轴,即取当前要排序的数组片段中间位置(这里的中间位置计算方式是先将i
和j
相加再除以 2)的元素作为枢轴。
(3)主循环
while i < j:while 1:i += 1if data[i] >= pivot:breakwhile 1:j -= 1if data[j] <= pivot:breakif i < j:data[i], data[j] = data[j], data[i]
- 外层
while
循环的条件是i < j
,只要这两个指针还没有相遇,就继续循环进行元素的比较和交换操作。 - 内层第一个
while
循环:不断将指针i
向右移动(通过i += 1
),直到找到一个大于等于枢轴pivot
的元素。这里使用while 1:
是为了让循环一直执行,直到满足if data[i] >= pivot:
这个条件时通过break
跳出循环。 - 内层第二个
while
循环:与第一个内层循环类似,不断将指针j
向左移动(通过j -= 1
),直到找到一个小于等于枢轴pivot
的元素。 - 当内层两个循环都找到合适的元素(即
i
指向大于等于枢轴的元素,j
指向小于等于枢轴的元素)后,如果i < j
,说明这两个元素的位置不符合快速排序的要求(左边应该是小于等于枢轴的元素,右边应该是大于等于枢轴的元素),此时就交换data[i]
和data[j]
这两个元素的位置,使得数组在i
和j
这两个位置上的元素更符合快速排序的分区要求。
(4)递归调用
quick_sort(l, j, data)
quick_sort(j + 1, r, data)
在完成一次i
和j
指针的移动和元素交换操作后,数组被以j
为界分成了两部分:左边部分(索引从l
到j
)和右边部分(索引从j + 1
到r
)。然后分别对这两部分递归地调用quick_sort
函数进行排序,直到整个数组都被排序完成。
4. main
函数详细解释
(1)设置初始边界
l = 0
r = n - 1
在main
函数中,首先设置了要排序的数组的初始左边界l
为 0,右边界r
为n - 1
,这里的n
是数组的长度,在后续的代码(在if __name__ == "__main__"
语句块中)会获取到用户输入的数组长度。
(2)调用快速排序函数
quick_sort(l, r, data)
接着,调用quick_sort
函数对整个数组(从索引 0 到索引n - 1
)进行排序,传入的参数是设置好的初始边界l
和r
以及要排序的数组data
。
5. if __name__ == "__main__"
语句块详细解释
(1)获取用户输入
n = int(input())
data = [int(x) for x in input().split()]
- 首先,通过
int(input())
获取用户输入的整数,这个整数表示要排序的数组的长度n
。 - 然后,通过
[int(x) for x in input().split()]
获取用户输入的以空格分隔的整数序列,并将其转换为整数列表data
,这个列表就是要进行排序的数组。
(2)调用main
函数并输出结果
main()
print(' '.join(list(map(str, data))))
- 首先调用
main
函数,在main
函数中会完成对数组data
的排序操作。 - 最后,通过
print(' '.join(list(map(str, data))))
将排序后的数组元素以空格分隔的字符串形式输出。这里先使用list(map(str, data))
将整数列表中的每个元素转换为字符串,然后使用join
方法将这些字符串用空格连接起来,形成一个可以直接输出的字符串形式。