排序

选择排序

首先在数组中找到最小的元素,然后把它和第一个元素交换。然后在剩余的元素中不断的找到最小者与第一个元素交换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
void selectSort(int a[], int n){
int i, j;
for (i = 0; i < n; i++){
int minIndex = i;
for(j = i + 1; j < n; j ++){
if (a[minIndex] > a[j]){
minIndex = j;
}
}
swap(a[minIndex], a[j]);
}
}
int main(){
int a[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
selectSort(a, 10);
return 0;
}

插入排序

在玩扑克牌的时候,如果都是从左到右的整理扑克,那么这个过程就是一个插入排序过程。

具体思想就是当前元素在前面已经排好序的数组中寻找合适的位置并插入进去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
void insertSort(int a[], int n){
for (int i = 1; i < n; i++){
for (int j = i; j > 0; j--){
if(a[j] < a[j-1]){
swap(a[j], a[j-1]);
}else{
break;
}
}
}
}

int main(){
int a[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
insertSort(a, 10);
return 0;
}

归并排序

对一个数组排序,可以将数组(递归)的分成两半进行排序,然后将结果合并起来。

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
#include <iostream>
using namespace std;

int aux[10];
void merge(int a[], int l, int mid, int r){
int i = l, j = mid + 1;
for(int k = l; k <= r; k++){
aux[k] = a[k];
}
for(int k = l; k <= r; k++){
if(i > mid){
a[k] = aux[j++];
}else if(j > r){
a[k] = aux[i++];
}else if(aux[i] > aux[j]){
a[k] = aux[j++];
}else{
a[k] = aux[i++];
}
}
}

void mergeSort(int a[], int l, int r){
if (l >= r) return;
int mid = l + (r - l) / 2;
mergeSort(a, l, mid);
mergeSort(a, mid + 1, r);
merge(a, l, mid, r);
}
int main(){
int a[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
mergeSort(a, 0, 9);
return 0;
}

快速排序

快速排序是一种分治算法。它是将一个数组分割成两个子数组,与归并排序不同的是:快速排序保证左边的数组元素都要小于右边的数组元素。

首先找到一个分割点,一般以数组的第一个元素作为这个分割点,先从左边往右边找。把比这个元素小的都放在左边,比它大的放在右边,然后又从右边往左边找。
当两个指针相遇时,我们只需要把该分割点的元素放到该位置即可(分割点)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

void quikSort(int a[], int begin, int end){
if(begin >= end)return;
int i = begin;
int j = end;
int key = a[i];
while(i < j){
while(a[j] >= key && j > i)j--;
a[i] = a[j];
while(a[i] <= key && j > i)i++;
a[j] = a[i];
}
a[i] = key;
quikSort(a, begin, i - 1);
quikSort(a, i + 1, end);
}

int main(){
int a[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
quikSort(a, 0, 9);
return 0;
}

堆排序

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
76
77
#include <iostream>
#define N 10
using namespace std;

int arr[N+1];
int count = 0;

void shiftUp(int k){
while(arr[k/2] < arr[k] && k > 1){
swap(arr[k/2], arr[k]);
k /= 2;
}
}

void insert(int v){
if(count + 1 > N) return;
arr[count + 1] = v;
count++;
shiftUp(count);
}

void shiftDown(int k){
while(2 * k <= count){
int j = 2 * k;
if(j + 1 <= count && arr[j + 1] > arr[j]){
j = j + 1;
}
if(arr[k] > arr[j]){
break;
}
swap(arr[j], arr[k]);
k = j;
}
}

int popMax(){
if (!count) return 0;
int v = arr[1];
swap(arr[1], arr[count]);
count--;
shiftDown(1);
return v;
}

void heapSort1(int a[], int n){
for (int i = 0; i < n; i++){
insert(a[i]);
}

for (int i = n - 1; i >= 0; i--){
a[i] = popMax();
}
}

void heapSort2(int a[], int n){
for (int i = 1; i <= n; i++){
arr[i] = a[i -1];
}

for(int i = n/2; i > 0; i--){
shiftDown(i);
}
count = n;
for (int i = n - 1; i >= 0; i--){
a[i] = popMax();
}
}

int main(){
int a[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
heapSort2(a, N);
for (int i = 0; i < N; i++){
cout << a[i] << " ";
}

return 0;
}