排序 Sort
动画
- 算法复杂度
冒泡排序 Bubble
相邻比较+换位1 | void BubbleSort(int *arr, int len) |
2 | { |
3 | int i, j, tmp; |
4 | for (i = 0; i < len - 1; i++) { |
5 | for (j = 0; j < len - i - 1; j++) { |
6 | if (arr[j] > arr[j+1]) { |
7 | tmp = arr[j]; |
8 | arr[j] = arr[j+1]; |
9 | arr[j+1] = tmp; |
10 | } |
11 | } |
12 | } |
13 | } |
14 | ``` |
15 | ![冒泡](algorithm-sort/BubbleSort.gif) |
16 |
|
17 | ## 选择排序 Select |
18 | 向后查找最小元, 与每一轮首位换位 |
19 | ```c |
20 | void SelectionSort(int *arr, int len) |
21 | { |
22 | int i, j, min, tmp; |
23 | for (i = 0; i < len - 1; i++) { |
24 | min = i; |
25 | for (j = i + 1; j < len; j++) { |
26 | if (arr[j] < arr[min]) { |
27 | min = j; |
28 | } |
29 | } |
30 | tmp = arr[min]; |
31 | arr[min] = arr[i]; |
32 | arr[i] = tmp; |
33 | } |
34 | } |
插入排序 Insert
从第二个开始抽出来, 和前面的比较并排位
1 | void InsertionSort(int *arr, int len) |
2 | { |
3 | int i, j, tmp; |
4 | for (i = 1; i < len; i++) { |
5 | |
6 | if (arr[i] < arr[i-1]) { |
7 | tmp = arr[i]; |
8 | for (j = i - 1; j >= 0 && arr[j] > tmp; j--) { |
9 | |
10 | arr[j+1] = arr[j]; |
11 | } |
12 | arr[j+1] = tmp; |
13 | } |
14 | } |
15 | } |
希尔排序 Shell
按增量分批做插入排序
1 |
|
2 | void ShellSort(int *arr, int size) |
3 | { |
4 | int i, j, tmp, increment; |
5 | for (increment = size/ 2; increment > 0; increment /= 2) { |
6 | for (i = increment; i < size; i++) { |
7 | |
8 | tmp = arr[i]; |
9 | for (j = i - increment; j >= 0 && tmp < arr[j]; j -= increment) { |
10 | arr[j + increment] = arr[j]; |
11 | } |
12 | arr[j + increment] = tmp; |
13 | } |
14 | } |
15 | } |
归并排序 Merge
分治法
1 | void merge(int arr[], int low, int mid, int high){ |
2 | int i, k; |
3 | int *tmp = (int *)malloc((high-low+1)*sizeof(int)); |
4 | |
5 | int left_low = low; |
6 | int left_high = mid; |
7 | int right_low = mid + 1; |
8 | int right_high = high; |
9 |
|
10 | for(k=0; left_low<=left_high && right_low<=right_high; k++){ |
11 | if(arr[left_low]<=arr[right_low]){ |
12 | tmp[k] = arr[left_low++]; |
13 | }else{ |
14 | tmp[k] = arr[right_low++]; |
15 | } |
16 | } |
17 |
|
18 | if(left_low <= left_high){ |
19 | |
20 | for(i=left_low;i<=left_high;i++) |
21 | tmp[k++] = arr[i]; |
22 | } |
23 |
|
24 | if(right_low <= right_high){ |
25 | |
26 | for(i=right_low; i<=right_high; i++) |
27 | tmp[k++] = arr[i]; |
28 | } |
29 |
|
30 | |
31 | for(i=0; i<high-low+1; i++) |
32 | arr[low+i] = tmp[i]; |
33 | free(tmp); |
34 | return; |
35 | } |
36 |
|
37 | void MergeSort(int arr[], unsigned int first, unsigned int last){ |
38 | int mid = 0; |
39 | if(first<last){ |
40 | mid = (first+last)/2; |
41 | |
42 | |
43 | MergeSort(arr, first, mid); |
44 | MergeSort(arr, mid+1,last); |
45 | merge(arr,first,mid,last); |
46 | } |
47 | return; |
48 | } |
快速排序 Quick
分块排序, 且左块皆小于右块
1 | void swap(int *a, int *b){ |
2 | int temp; |
3 | temp = *a; |
4 | *a = *b; |
5 | *b = temp; |
6 | } |
7 | void QuickSort(int *arr, int maxlen, int begin, int end){ |
8 | void QuickSort(int *arr, int maxlen, int begin, int end) |
9 | { |
10 | printf("\nQuickSort(%d->%d)\n", begin, end); |
11 | int i, store; |
12 | if (begin - end >= -1){ |
13 | return; |
14 | } |
15 | |
16 | i = begin + 1; |
17 | store = begin + 1; |
18 | while (i < end){ |
19 | if (arr[i] < arr[begin]){ |
20 | swap(&arr[i], &arr[store]); |
21 | store++; |
22 | } |
23 | i++; |
24 | } |
25 |
|
26 | swap(&arr[store - 1], &arr[begin]); |
27 | printf("\n"); |
28 | QuickSort(arr, maxlen, begin, store - 1); |
29 | QuickSort(arr, maxlen, store, end); |
30 | } |
1 | void QuickSort(int *arr, int maxlen, int begin, int end){ |
2 | int i, j; |
3 | if (begin < end) { |
4 | |
5 | i = begin + 1; |
6 | j = end; |
7 | while (i < j) { |
8 | if(arr[i] > arr[begin]) { |
9 | swap(&arr[i], &arr[j]); |
10 | j--; |
11 | } else { |
12 | i++; |
13 | } |
14 | } |
15 | if (arr[i] >= arr[begin]) { |
16 | i--; |
17 | } |
18 | swap(&arr[begin], &arr[i]); |
19 | QuickSort(arr, maxlen, begin, i); |
20 | QuickSort(arr, maxlen, j, end); |
21 | } |
22 | } |
堆排序 Heap
1 | #define LeftChild(i) (2*(i)+1) |
2 |
|
3 | void PercDown(int A[],int i, int N){ |
4 | int Child; |
5 | int Tmp; |
6 | for (Tmp=A[i];LeftChild(i)<N;i=Child){ |
7 | Child = LeftChild(i); |
8 | if(Child != N-1 && A[Child + 1] > A[Child]){ |
9 | Child++; |
10 | } |
11 | if(Tmp < A[Child]){ |
12 | A[i] = A[Child]; |
13 | }else{ |
14 | break; |
15 | } |
16 | } |
17 | A[i] = Tmp; |
18 | } |
19 |
|
20 | void HeapSort(int A[],int N){ |
21 | int i; |
22 | for (i=N/2;i>=0;i--){ |
23 | PercDown(A,i,N); |
24 | } |
25 | for (i = N-1;i>0;i--){ |
26 | swap(&A[0],&A[i]); |
27 | PercDown(A,0,i); |
28 | } |
29 | } |
基数排序
计数排序
桶排序
随机快速排序