快速排序是什么?
快速排序的核心思想是选择一个基准元素,并将数组中的元素分为两个子数组,一个包含所有小于基准的元素,另一个包含所有大于或等于基准的元素。这个过程称为分区操作。然后,递归地在这两个子数组上重复相同的过程,直到每个子数组只包含一个元素或为空,此时数组就被排序完成了。
算法性能:
快速排序算法的性能主要取决于几个因素:包括数据集的初始顺序、基准数的选择以及递归调用的深度。在最理想的情况下,每次递归都能将数据集大致均匀地分成两半,这样算法的时间复杂度为O(n log n),其中n是待排序元素的数量。
在最坏的情况下:例如当输入数组已经是有序的或者逆序的时候,快速排序的性能会退化为O(n^2),因为每次递归都只会移动一个元素到其最终位置。
平均情况下:快速排序的性能接近O(n log n),这使得它在实际应用中成为一种非常高效的排序算法。
接下来我们来看看代码:
def Quicksortpivot(arr,start,end): #寻找出基准数的下标 # 并把所有小于等于它的数放在左边,大于它的数放在右边 pivot=start #令最左边的数为基准数 j=start+1 #j代表大于基准数的数的下标的左边界 for i in range(start+1,end+1): if arr[i]<=arr[pivot]: #如果小于等于基准数,把它放在左边界 arr[i],arr[j]=arr[j],arr[i] j+=1 #保证j下标以前的数都是小于等于基准数的数 #如果当前数大于基准数就不做任何处理 arr[pivot],arr[j-1]=arr[j-1],arr[pivot] #把基准数和小于它的所有数进行交换 pivot=j-1 #更新基准数的下标 # 打印看看效果 print(arr[pivot],arr[start:pivot],arr[pivot+1:end+1]) return pivot def quicksort(arr,start,end): if start>=end: #如果只有一个数字就直接返回。这里很关键,递归的终止条件。 return pivot=Quicksortpivot(arr,start,end) #获取基准数的下标 quicksort(arr,start,pivot-1) #递归调用基准数左边的部分 quicksort(arr,pivot+1,end) #递归调用基准数右边的部分 arr=[4,2,3,6,43,5,6,5,1,7] #任意一个数组排序看看 quicksort(arr,0,len(arr)-1) #注意:end是数组的最后一个,就是数组长度减一 print(arr)
工作原理:
Quicksortpivot 函数
这个函数的主要目的是选择一个“基准数”(pivot),然后将数组中小于或等于基准数的元素放在基准数的左边,大于基准数的元素放在基准数的右边。
-
初始化:
pivot
初始化为start
,即选择数组的第一个元素作为初始的基准数。j
初始化为start+1
,用于标记大于基准数的数的下标的左边界。
-
遍历数组:
- 使用
for
循环从start+1
到end
遍历数组。 - 如果当前元素
arr[i]
小于或等于基准数arr[pivot]
,则将其与arr[j]
交换,并将j
的值加1。这样,j
左边的所有元素都小于或等于基准数。
- 使用
-
最终交换:
- 在遍历结束后,将基准数
arr[pivot]
与arr[j-1]
交换。此时,j-1
左边的所有元素都小于或等于基准数,j
及右边的所有元素都大于基准数。
- 在遍历结束后,将基准数
-
返回:
- 返回新的基准数的下标
j-1
。
- 返回新的基准数的下标
quicksort 函数
这是快速排序的主函数,它采用递归的方式对数组进行排序。
-
递归终止条件:
- 如果
start
大于或等于end
,说明当前子数组的长度为0或1,无需排序,直接返回。
- 如果
-
获取基准数下标:
- 调用
Quicksortpivot
函数获取基准数的下标。
- 调用
-
递归排序:
- 对基准数左边的子数组进行递归排序,调用
quicksort(arr, start, pivot-1)
。 - 对基准数右边的子数组进行递归排序,调用
quicksort(arr, pivot+1, end)
- 对基准数左边的子数组进行递归排序,调用
这样就算完成了快速排序,值得注意的是,快速排序并不稳定,接下来我会去介绍其它几种稳定的排序算法。