Life sucks, but you're gonna love it.

0%

Algorithm | Sorting

排序算法

Quick Sort - 快速排序

快排的主要思想是divide and conquer,是把一个大问题划分成几个小问题然后再合并在一起的方法。

核心问题就是找到一个pivot的位置,使得pivot左边的数字都小于pivot,而右边的数字都大于pivot,这样pivot的位置就定了,然后我们再分别对两边的数字再进行:寻找pivot - 找左边 - 找右边。

这种循环进行的操作的好处在于,我们找到的pivot的位置是正确的,然后在每个小问题中,不断地实施这个操作,就可以让每个数字找到合适自己的位置。

假设我们有一个可以帮助我们寻找pivot的函数 Partition,那么排序的过程就可以写为:

1
2
3
4
5
6
7
8
9
def quicksort(arr, low, high):

if low < high:
pivot = partition(arr, low, high)

quicksort(arr, low, pivot-1)
quicksort(arr, pivot+1, high)

return arr

返回pivot的位置可以帮助我们固定pivot,更好得对pivot之前和之后个数组进行操作。

那么问题是,现在如何定义函数Partition?

函数Partition的主要作用是,将输入array中的某一个数定义为pivot,并且确定它在array中的位置。我们一般选取array最后一个值作为pivot,然后将这个pivot放在正确的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def partition(arr, low, high):
i = 0
j = 0
mid = (low + high)//2
arr[mid], arr[-1] = arr[-1], arr[mid]
while i < len(arr) - 1:

if arr[i] < arr[-1]:
arr[i], arr[j] = arr[j], arr[i]
# print(arr)
j += 1
i += 1

arr[j], arr[-1] = arr[-1], arr[j]

return j

Bubble Sort - 冒泡排序

冒泡排序的核心思想在于两两比较数字之间的大小然后将最大的移动到最后。

第一步bul

时间复杂度 : O(n^2)

空间复杂度:O(1)

1
2
3
4
5
6
7
8
9
10
def bubblesort(arr):
k = len(arr)
while k > 0:
for i in range(1, k):
if arr[i] < arr[i-1]:
arr[i], arr[i-1] = arr[i-1], arr[i]
i += 1
k -= 1

return arr

算是比较简单明白的排序,注意一点的是 while k > 0 和后面的k -= 0 同样可以用一句 for _ in range(len(arr)) 代替,这样时间复杂度会更高。之前用while是考虑到后面比较大的数字已经放在最后就不需要考虑了。时间复杂度是 $O(n^2)$

Merge Sort - 归并排序

归并排序的方法主要思想也是divide and conquer,既然如此,我们需要把大的排序分解成小的序列,然后排序之后再合并在一起。

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
32
33
def merge(left, right):
# print(left, right)
i = 0
j = 0
merge_arr = []
while i < len(left) and j < len(right):
if left[i] <= right[j]:
merge_arr.append(left[i])
i += 1
else:
merge_arr.append(right[j])
j += 1
if i == len(left):
merge_arr = merge_arr + right[j:]
else:
merge_arr = merge_arr + left[i:]
print(merge_arr)
return merge_arr


def mergeSort(arr, start, end):

if start == end:

return arr[start:end+1]

mid = (start + end)//2
left = mergeSort(arr, start, mid)
right = mergeSort(arr, mid + 1, end)

merge_arr = merge(left, right)

return merge_arr

Insertion Sort - 插入排序

插入排序的思想是将未排序的值插入到之前的已经排序的数列中去。

时间复杂度:O(n^2)

空间复杂度:O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
def insertionsort(arr):

for i in range(1, len(arr)):
print(arr)
k = i
while k > 0:
if arr[k] < arr[k - 1]:
arr[k], arr[k-1] = arr[k-1], arr[k]
k -= 1
else:
break

return arr