经典排序算法回顾

经典排序算法总结

参考:https://blog.csdn.net/kuaizi_sophia/article/details/87954222

img

冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void bubbleSort(int a[], int n) {
for (int i = 0; i < n; ++i) {
// 当前轮是否发生过交换事件标志位,若未发生交换,则表明列表已有序。
bool isExchanged = false;
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
isExchanged = true;
}
}
if (!isExchanged) {
break;
}
}
}

选择排序

1
2
3
4
5
6
7
8
9
10
11
12
13
void selectSort(vector<int>& array){
for (int i = 0; i < array.size(); i++){
int minIndex = i;
for (int j = i + 1; j < array.size(); j++){
if (array[minIndex] > array[j]){
minIndex = j;
}
}
if (minIndex != i){
swap(array[i], array[minIndex]);
}
}
}

插入排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void insertionSort(vector<int>& array) {
// i 代表无序序列首元素(无序序列前为有序序列)
int i = 1;
while (i < array.size()) {
int j = i - 1;
int itermToInsert = array[i];
while (j >= 0) {
if (array[j] >= itermToInsert) {
array[j + 1] = array[j];
j--;
} else {
break;
}
}
array[j + 1] = itermToInsert;
i++;
}
}

希尔排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void shellSort(vector<int>& array){
int n = array.size();
for (int gap = n / 2; gap >= 1; gap /= 2){
for (int i = gap; i < n; i++){
// 使用插入排序算法,将元素依次插入所在小组的已排序列表中
// 待插入元素
int itermToInsert = array[i];
int j = i - gap;
while (j >= 0 && array[j] >= itermToInsert){
array[j + gap] = array[j];
j -= gap;
}
array[j + gap] = itermToInsert;
}
}
}

归并排序

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
// 合并两个区间并排序
void merge(int a[], int begin, int mid, int end) {
int count = end - begin + 1;
int* p = new int[count]();
int i = begin, j = mid + 1, index = 0;
while (i <= mid && j <= end) {
p[index++] = a[i] <= a[j] ? a[i++] : a[j++];
}
while (j <= end) {
p[index++] = a[j++];
}
while (i <= mid) {
p[index++] = a[i++];
}
for (int i = 0; i < count; ++i) {
a[begin++] = p[i];
}
delete[]p;
}

// 归并排序(递归)
void mergeSort_Recursion(int a[], int begin, int end) {
if (begin >= end) {
return;
}
int mid = (begin + end) / 2;
mergeSort_Recursion(a, begin, mid);
mergeSort_Recursion(a, mid + 1, end);
merge(a, begin, mid, end);
}

// 归并排序(迭代)
void mergeSort_Iteration(int a[], int begin, int end) {
int count = end - begin + 1;
int left;
for (int step = 1; step < count; step *= 2) {
left = begin;
while (left + step < end) {
int mid = left + step - 1;
int right = (mid + step) < end ? (mid + step) : end;
merge(a, left, mid, right);
left = right + 1;
}
}
}

快速排序

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
// 将区间按照基准切分为两个部分,左边的数均小于基准,右边的数均大于基准
int partition(int a[], int left, int right) {
// 基准
int pivot = a[right];
int tail = left - 1;
for (int i = left; i < right; ++i) {
if (a[i] <= pivot) {
swap(a[i], a[++tail]);
}
}
swap(a[tail + 1], a[right]);
return tail + 1;
}

// 快速排序(递归)
void quickSort(int a[], int left, int right) {
if (left < right) {
int pivot = partition(a, left, right);
quickSort(a, left, pivot - 1);
quickSort(a, pivot + 1, right);
}
}

// 快速排序(尾递归)
void quickSort_tailRecursion(int a[], int left, int right) {
while (left < right) {
int pivot = partition(a, left, right);
quickSort_tailRecursion(a, left, pivot - 1);
left = pivot + 1;
}
}

堆排序

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
// 建堆的单次操作,实现了把某一元素在建堆时正确归位
void heapify(int a[], int cur, int size) {
int lChild = 2 * cur + 1;
int rChild = 2 * cur + 2;
int max = cur;
if (lChild < size && a[max] < a[lChild]) {
max = lChild;
}
if (rChild < size && a[max] < a[rChild]) {
max = rChild;
}
if (cur != max) {
swap(a[cur], a[max]);
heapify(a, max, size);
}
}

// 建堆(大顶堆)
void buildHeap(int a[], int n) {
for (int i = n / 2 - 1; i >= 0; --i) {
heapify(a, i, n);
}
}

// 堆排序函数
void heapSort(int a[], int left, int right) {
int size = right - left + 1;
buildHeap(a, size);
while (size > 1) {
swap(a[0], a[--size]);
heapify(a, 0, size);
}
}