快排
注意:
- 快排是不稳定排序
思路:
选基数,双指针移动/交换,分治
示例:
> 坐在马桶上看算法:快速排序 - 51CTO.COM http://developer.51cto.com/art/201403/430986.htm
> 快速排序(三种算法实现和非递归实现) - CSDN博客 https://blog.csdn.net/qq_36528114/article/details/78667034
第一轮
i j
6 1 2 7 9 3 4 5 10 8
基数 x=6
先从 j 往前遍历(j--),遇到小于 x 的数停下,再从 i 往后遍历,遇到大于 x 的数停下,交换 *j 和 *i
i j
6 1 2 7 9 3 4 5 10 8
6 1 2 5 9 3 4 7 10 8(交换后)
重复以上步骤,继续先移动 j,再移动 i
i j
6 1 2 5 9 3 4 7 10 8
6 1 2 5 4 3 9 7 10 8(交换后)
ij
6 1 2 5 4 3 9 7 10 8
6 1 2 5 4 3 9 7 10 8(交换后)
此时 i 与 j 相遇,交换 *i 与 *x
ij
3 1 2 5 4 6 9 7 10 8
第一轮完成,之后递归完成子部分
基数的选择不固定,一般选择第一个或最后一个,或中位数
1 | void quickSort(vector<int> &array, int low, int high){ |
归并排序
- 归并排序是稳定排序
思路:
分治
划分子区间、子区间排序、合并子区间
1 | void mergeSort(vector<int> &array, int low, int high){ |
链表归并
1 | ListNode *findhalf(ListNode *head){ |
堆排序
堆排序是不稳定排序
堆的性质:
每个节点的值小于等于其父节点 或 大于等于父节点;前者称为“最大堆”,用于升序,后者为“最小堆”,用于降序堆是一棵完全二叉树,因此常用数组进行模拟
思路:
建堆:建堆的过程实际上就是从最后一个 非叶子节点 开始不断向前做自顶向下的调整
堆排序:
建完堆后,每次交换堆顶和堆尾, 然后对 a[0..n-1] 重新调整
每次调整的操作时间复杂度为 O(logn)
建堆的时间复杂度为 O(N)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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52int heapsize = 0;
void maxHeapify(vector<int> &array, int k){
//将元素k向下进行调整,即i是k的左孩子(i在k下)
// 注意:自顶向下的操作只完成了一个节点的调整
for(int i = 2*k+1; i < heapsize; i=i*2+1){
//当前调整节点为k,和其子节点的最大值比较若小于则违背最大堆性质
int largest = array[k];
//largest=max(a[left],a[right])并且在不越界的情况下,right<heapsize
// 实际上,以下操作就是为了找出 a[i] 和 a[i*2+1]、a[i*2+2] 之中的最大值
if(i+1 < heapsize && array[i] < array[i+1])
i++;
//当前节点已满足大于其子节点,调整完毕
if(largest >= array[i]) break;
//否则a[i] 不是最大的,说明还需继续调整
else{
swap(array[k], array[i]);
k = i;
}
}
}
void buildMaxHeap(vector<int> &array){
//全局变量来控制堆的调整
heapsize = int(array.size());
// 建堆的过程实际上就是从最后一个 **非叶子节点** 开始不断往前调整
for (int i = int(array.size()>>1); i >= 0; --i){
maxHeapify(array, i);
}
}
void heapSort(vector<int> &array){
buildMaxHeap(array);
for(int i = int(array.size() - 1); i >= 1; --i){
//堆顶元素array[0]即最大值换到堆尾,再重新调整堆
swap(array[i], array[0]);
//从堆中删除该元素
heapsize--;
maxHeapify(array, 0);
}
}
int main(){
vector<int> vec = {45, 68, 20, 39, 88, 97, 46, 59};
heapSort(vec);
for(int i = 0; i < vec.size(); ++i)
cout << vec[i] << " ";
cout << endl;
}
直接插入排序和希尔排序
1 | void insertSort(vector<int> &array){ |
冒泡排序
1 | void bubbleSort(vector<int> &array){ |
简单选择排序
1 | void selectSort(vector<int> &array){ |