前言
排序算法是面试中的重点考点,这部分算法不是很难,但细节处很凸显基本功,如果深究起来怕是很多人都回答不清的。
今天就来借着Leetcode的一道模板题来讲讲各个算法的实现(Python),以及一些注意事项,不足之处欢迎指正。
涉及算法
- 冒泡排序
- 快速排序
- 归并排序
- 堆排序
- 选择排序
- 插入排序
- shell排序
Leetcode测评地址 - 75 Sort Colors Medium难度
正文
先解释一下题意:
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
其实很简单,给数组排一下序就行了,不过用自带的sort就没意思了,这题正好可以用来测一下各个排序算法。
- 冒泡排序
它的思想是每次让一个元素和它相邻的元素对比并交换值,每一趟下来都有一个元素被冒泡到最顶端,也就是说它排好了,下一趟排序就不用和它比较了。
所以每一趟需要对比的次数都会-1,实现起来,第一层循环控制比较次数,第二层循环执行冒泡操作。
1 |
class : |
后面就不写全部的类了,只给出方法。
快速排序
快排的思想就是选取一个基准数,把比它小的值放在左边,比它大的值放在右边,然后对左边和右边的区间分别重复上述步骤,直到区间只剩一个元素。
递归实现,不过不是原地的,这题提交不过。1
2
3
4
5
6
7
8def quick_sort(self, nums: List[int]) -> None:
if len(nums) < 2:
return nums
pivit_index = 0
pivit = nums[pivit_index]
left = [i for i in nums[pivit_index + 1:] if i <= pivit]
right = [i for i in nums[pivit_index + 1:] if i > pivit]
return self.quick_sort(left) + [pivit] + self.quick_sort(right)非递归版,原地排序,用栈保存区间的上界和下界
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
26def partition(self, nums, l, r):
pivit = nums[l]
while l < r:
while l < r and nums[r] >= pivit:
r -= 1
nums[l] = nums[r]
while l < r and nums[l] <= pivit:
l += 1
nums[r] = nums[l]
nums[l] = pivit
return l
def quick_sort(self, nums: List[int]) -> None:
stk = []
stk.append(len(nums) - 1)
stk.append(0)
while stk:
l = stk.pop()
r = stk.pop()
mid = self.partition(nums, l, r)
if l < mid:
stk.append(mid - 1)
stk.append(l)
if r > mid:
stk.append(r)
stk.append(mid + 1)