十大排序

十大排序算法

经典图镇楼

image-festival

在STL中,是以函数sort实现的

1
2
void sort(iterator begin, iterator end);
void sort(iterator begin, iterator end, comparator cmp);

迭代器必须支持随机访问。sort算法并不能保证相等的项保持他们原有的顺序。(若这很重要,可以使用stable_sort)这里一般使用的是快速排序。

冒泡排序

image-festival
1
2
3
4
5
6
7
8
template<typename T> //整数或浮点数皆可使用,若使用类(class)或结构体(struct)时必须重载大于(>)运算符
void bubble_sort(T arr[], int len) {
int i, j;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}

选择排序

image-festival
1
2
3
4
5
6
7
8
9
10
template<typename T> //整数或浮点数皆可使用,若使用类(class)或结构体(struct)时必须重载大于(>)运算符
void selection_sort(std::vector<T>& arr) {
for (int i = 0; i < arr.size() - 1; i++) {
int min = i;
for (int j = i + 1; j < arr.size(); j++)
if (arr[j] < arr[min])
min = j;
std::swap(arr[i], arr[min]);
}
}

插入排序

image-festival
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template<typename T>
public static void InsertSort(int[] array)
{
for(int i = 1;i < array.length;i++)
{
int temp = array[i];
for(int j = i - 1;j >= 0;j--)
{
if(array[j] > temp)
{
array[j + 1] = array[j];
array[j] = temp;
}
else
break;
}
}
}

希尔排序

image-festival
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename T>
void shell_sort(T array[], int length) {
int h = 1;
while (h < length / 3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (int i = h; i < length; i++) {
for (int j = i; j >= h && array[j] < array[j - h]; j -= h) {
std::swap(array[j], array[j - h]);
}
}
h = h / 3;
}
}

归并排序

image-festival
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
template<typename T> 
void merge_sort(T arr[], int len) {
T *a = arr;
T *b = new T[len];
for (int seg = 1; seg < len; seg += seg) {
for (int start = 0; start < len; start += seg + seg) {
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
T *temp = a;
a = b;
b = temp;
}
if (a != arr) {
for (int i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
delete[] b;
}

快速排序

image-festival

迭代法

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
// 参考:http://www.dutor.net/index.php/2011/04/recursive-iterative-quick-sort/
struct Range {
int start, end;
Range(int s = 0, int e = 0) {
start = s, end = e;
}
};
template <typename T>
void quick_sort(T arr[], const int len) {
if (len <= 0)
return;
Range r[len];
int p = 0;
r[p++] = Range(0, len - 1);
while (p) {
Range range = r[--p];
if (range.start >= range.end)
continue;
T mid = arr[range.end];
int left = range.start, right = range.end - 1;
while (left < right) {
while (arr[left] < mid && left < right) left++;
while (arr[right] >= mid && left < right) right--;
std::swap(arr[left], arr[right]);
}
if (arr[left] >= arr[range.end])
std::swap(arr[left], arr[range.end]);
else
left++;
r[p++] = Range(range.start, left - 1);
r[p++] = Range(left + 1, range.end);
}
}

递归法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <typename T>
void quick_sort_recursive(T arr[], int start, int end) {
if (start >= end)
return;
T mid = arr[end];
int left = start, right = end - 1;
while (left < right) { //在整个范围内搜寻比枢纽元值小或大的元素,然后将左侧元素与右侧元素交换
while (arr[left] < mid && left < right) //试图在左侧找到一个比枢纽元更大的元素
left++;
while (arr[right] >= mid && left < right) //试图在右侧找到一个比枢纽元更小的元素
right--;
std::swap(arr[left], arr[right]); //交换元素
}
if (arr[left] >= arr[end])
std::swap(arr[left], arr[end]);
else
left++;
quick_sort_recursive(arr, start, left - 1);
quick_sort_recursive(arr, left + 1, end);
}
template <typename T>
void quick_sort(T arr[], int len) {
quick_sort_recursive(arr, 0, len - 1);
}

堆排序

heapSort
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
#include <iostream>
#include <algorithm>
using namespace std;
//堆调整
void max_heapify(int arr[], int start, int end) {

int dad = start;
int son = dad * 2 + 1;
while (son <= end) { // 要求子节点在范围内
if (son + 1 <= end && arr[son] < arr[son + 1]) // 判断是否有另一个更大的子节点
son++;
if (arr[dad] > arr[son]) // 如果父节点最大,则不需要交换
return;
else { // 交换父子位置后,进行子孙的比较
swap(arr[dad], arr[son]);
dad = son;
son = son * 2 + 1;
}
}
}

void heap_sort(int arr[], int len) {
//初始化,使初始数组变成大顶堆,时间复杂度为nlogn
for (int i = len / 2 - 1; i >= 0; i--)
max_heapify(arr, i, len - 1);
//将堆顶放到最后,然后再调节为大顶堆,复杂度也为nlogn
for (int i = len - 1; i > 0; i--) {
swap(arr[0], arr[i]);
max_heapify(arr, 0, i - 1);
}
}

int main() {
int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
int len = (int) sizeof(arr) / sizeof(*arr);
heap_sort(arr, len);
for (int i = 0; i < len; i++)
cout << arr[i] << ' ';
cout << endl;
return 0;
}

计数排序

未完待续……

桶排序

基数排序

参考资料

[1]https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

[2]https://zhuanlan.zhihu.com/p/61488756


十大排序
https://wuhlan3.github.io/2020/10/07/十大排序/
Author
Wuhlan3
Posted on
October 7, 2020
Licensed under