快速排序
快速排序(Quick Sort),是冒泡排序的一种改进,由C.A.R.Hoare在1960年提出。
快速排序的主要思想是通过一排排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,最终使整个数据编程有序序列。
算法介绍
原理
1.在数据集之中,选择一个元素作为“基准”(pivot)
2.所有小于“基准”的元素,都移动到“基准”的左边;所有大于“基准”的元素,都移动到“基准”的右边。这个操作称为分区(partition)
3.对“基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
Partion-挖坑法(双指针法)
例如,有如下数组需要排序
在数组两端设两个指针l和r
r指向1,1小于4,挖坑,1填到原来4的位置,
l向后移动,指向7,7大于4,挖坑,7填到原来1的位置,
r向前移动,指向8,8大于4,不动
r继续向前移动,指向2,2小于4,挖坑,2填到原来7的位置,
l向后移动,指向6,6大于4,挖坑,6填到原来2的位置,
r向前移动,指向3,3小于4,挖坑,3填到原来6的位置,
l向后移动,指向5,5大于5,挖坑,5填到原来3的位置,
r往前移动,l和r重合,将初始pivot(4)填入原来5的位置,第一趟排序结束。
Partion-指针交换法
双指针同时移动
l和r,r指向1,小于4,l向后移动,指向7,此时,1和7进行交换。
r向前移动,指向8,继续向前移动,指向3,l向后移动,指向6,此时2和6进行交换。
r向前移动,指向3,l向后移动,指向5,此时3和5进行交换。
r继续往前移动,l和r相遇,
因为r先移动,所以3再和4进行比较,3小于4,所以进行交换,
算法跳出
leetcode 215
在未排序的数组中找到第K个最大的元素。请注意,你需要找的是数组排序后的第K个最大的元素,而不是第K个不同的元素
示例1:
输入:[3,2,1,5,6,4]和k = 2
输出:5
class Solution:
def findKthLargest(self,nums,k):
# 快排
self._k = len(nums) - k
return self.quicksort(nums,0,len(nums)-1)
def quicksort(self,nums,left,right):
if left == right:
return nums[left]
pivot = self.partition(nums,left,right)
if pivot == self._k:
# 如果我们要找的第K大的数 刚好是pivot的位置 就找到了第K个最大元素
return nums[pivot]
elif pivot < self._k:
# 基准小于_k 就往右边找
return self.quicksort(nums,pivot+1,right)
else:
# 太大了 就往左边找
return self.quicksort(nums,left,pivot-1)
def partition(self,nums,left,right):
# 确定基准元素的最终位置
pivot = nums[left]
i,j = left,right
while i < j:
while i < j and nums[j] >= pivot:
j -= 1
if i < j:
nums[i] = nums[j]
i += 1
while i < j and nums[i] <= pivot:
i += 1
if i < j:
nums[j] = nums[i]
j -= 1
nums[i] = pivot
return i