文章目录
-
- 一、快速排序
- 二、堆排序
- 三、归并排序
一、快速排序
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
- 挑选基准值:从数列中挑出一个元素,称为”基准”(pivot);
- 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
- 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。
class Solution:
'''快速排序'''
def partition(self, low, high, nums):
'''取数组中间值作为枢轴'''
if low >= high:
return
i, j = low, high
nums[low], nums[(i + j) // 2] = nums[(i + j) // 2], nums[low]
pivot = nums[low]
while i < j:
while i < j and nums[j] >= pivot:
j -= 1
nums[i] = nums[j]
while i < j and nums[i] < pivot:
i += 1
nums[j] = nums[i]
nums[i] = pivot
return i
def quickSort(self, low, high, nums):
'''low:数组左边界,high:数组右边界(n-1)'''
if low >= high:
return
pivot = self.partition(low, high, nums)
self.quickSort(low, pivot-1, nums)
self.quickSort(pivot+1, high, nums)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
时间复杂度:O(nlog2n)。 最好情况(待排序列接近无序):O(nlog2n);最坏情况(待排序列接近有序):O(n2)
空间复杂度:O(nlogn)
稳定性:快排是一种不稳定排序,比如基准值的前后都存在与基准值相同的元素,那么相同值就会被放在一边,这样就打乱了之前的相对顺序
比较性:因为排序时元素之间需要比较,所以是比较排序。
二、堆排序
class Solution:
'''堆排序(大顶堆)'''
def update(self, i, high, nums):
j = 2 * i + 1
while j < high:
if j + 1 < high and nums[j] < nums[j + 1]:
j += 1
# 已经调整完毕,提前截止
if nums[i] >= nums[j]:
break
else:
nums[i], nums[j] = nums[j], nums[i]
i = j
j = 2 * i + 1
def createMaxHeap(self, high, nums):
'''向下调整,从n/2开始'''
for i in range(high // 2, -1, -1):
self.update(i, high, nums)
def heapSort(self, nums):
n = len(nums)
self.createMaxHeap(n, nums)
for i in range(n):
##把堆顶元素置换到数组最后
nums[0], nums[n-i-1] = nums[n-i-1], nums[0]
self.update(0, n-i-1, nums)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
时间复杂度:O(nlogn),建堆复杂度约为O(N),调整O(logN)
空间复杂度:O(1)
特性:是一种不稳定排序
三、归并排序
class Solution:
def merge(self, nums, l, mid, r):
temp = []
i, j = l, mid+1
while i <= mid and j <= r:
if nums[i] <= nums[j]:
temp.append(nums[i])
i += 1
else:
temp.append(nums[j])
j += 1
while i <= mid:
temp.append(nums[i])
i += 1
while j <= r:
temp.append(nums[j])
j += 1
nums[l:r+1] = temp
def mergeSort(self, nums, l, r):
if l >= r:
return
mid = (l + r) // 2
self.mergeSort(nums, l, mid)
self.mergeSort(nums, mid+1, r)
self.merge(nums, l, mid, r)
nums = [5,2,3,1]
Solution().mergeSort(nums, 0, len(nums)-1)
print(nums)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
时间复杂度:O(nlogn)。 最好情况, 最坏情况均为O(nlogn)
空间复杂度:O(n)
特性:是一种稳定排序