Sorting Algorithms
[TOC]
插入排序
- 概念: 从头到尾逐个处理数据,将当前数据和它前面的序列进行比较:若当前数据小于前一个数据,则交换位置;否则移动数组,处理下一个数据
- 特征: 稳定
- 性能: O(n) / O(n^2) / O(n^2)
- 代码:
1 | template<class type> |
冒泡排序
- 概念: 从头到尾逐个处理数据,每次将当前数据和它后面的序列进行比较:若当前数据大于后一个数据,则交换位置,并后移下标;否则仅后移下标
- 特征: 稳定
- 性能: O(n^2) / O(n^2) / O(n^2)
- 代码:
1 | template<class type> |
选择排序
- 概念: 第i次选择数组中第i小的数值,插入到第i个位置
- 特征: 不稳定
- 性能: O(n^2) / O(n^2) / O(n^2)
- 代码:
1 | template<class type> |
shell排序
概念: 用 Gap 将数组等分划分,对较小的划分数组进行插入排序,再将较小的划分数组合并为较大的数据,并进行插入排序,直到得到完整的有序数组
特征: 不稳定
性能 (Gap = 2): O(n) / O(n^2) / O(n^1.5)
代码:
1 | template<class type> |
快速排序
- 概念: 选择数组中的一个数字作为轴值,将比轴值小的数放在轴值左边,比轴值大的数放在轴值右边,并通过递归依次处理轴值左边和右边的序列
- 特征: 不稳定
- 性能: O(nlogn) / O(n^2) / O(nlogn)
- 代码:
1 | template<class type> |
归并排序
- 概念: 每次通过递归将数组划分为长度相同的子序列,并用临时数组来进行排序;接着将子序列合并为一个更大的数组并排序
- 特征: 稳定 / 使用等长度的临时数组 (也可以通过 reverse 来实现)
- 性能: O(nlogn) / O(nlogn) / O(nlogn)
- 代码:
1 | template<class type> |
- 优化: 不需要临时数组
1 | template<class type> |
堆排序
概念: 构建最大堆,每次将堆顶元素弹出,并用剩余元素继续构建最大堆,直到空堆
特征: 不稳定
性能: O(nlogn)
代码:
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76template<class type>
void pushHeap(type Arr[], int hole){
type t = Arr[hole];
int parent = (hole - 1) / 2;
while(hole > 0 && Arr[parent] < t){
Arr[hole] = Arr[parent];
hole = parent;
parent = (hole - 1) / 2;
}
Arr[hole] = t;
}
template<class type>
void popHeap(type Arr[], int size){
type t = Arr[size-1];
Arr[size-1] = Arr[0];
size--;
int hole = 0;
int child = 2 * (hole + 1);
while(child < size){
if(Arr[child - 1] > Arr[child])
child--;
Arr[hole] = Arr[child];
hole = child;
child = 2 * (hole + 1);
}
if(child == size){
Arr[hole] = Arr[child - 1];
hole = child - 1;
}
Arr[hole] = t;
pushHeap(Arr, hole);
}
template<class type>
void makeHeap(type Arr[], int size){
for(int i = 0; i < size; i++)
pushHeap(Arr, i);
}
template<class type>
void makeHeap2(type Arr[], int size){
int parent = (size - 2) / 2;
while(parent >= 0){
int hole = parent;
int child = 2 * (hole + 1);
type t = Arr[hole];
while(child < size){
if(Arr[child - 1] > Arr[child])
child--;
Arr[hole] = Arr[child];
hole = child;
child = 2 * (hole + 1);
}
if(child == size){
Arr[hole] = Arr[child - 1];
hole = child - 1;
}
Arr[hole] = t;
pushHeap(Arr, hole);
parent--;
}
}
template<class type>
void heapSort(type Arr[], int size){
makeHeap(Arr, size);
// makeHeap2(Arr, size);
for(int j = size; j>1; j--)
popHeap(Arr, j);
}