本节中所讲的排序均以升序为例。
一、冒泡排序
1. 基本思想:
从左到右,两两比较;如果发现前者比后者大,则交换元素。每一轮比较完毕后,序列中最大的一个元素会至于最后。流程图如下:
2. 代码清单:
void bubbleSort(int *a, int length) { int i,j; for (i = length - 1; i >= 0; i--) { for (j = 0; j < i; j++) { if (a[j] > a[j + 1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } } int main(int argc, const char * argv[]) { int a[] = {2, 4, 9, 1, 0, 3}; bubbleSort(a, 6); for (int i = 0; i < 6; i++) { printf("%d\n", a[i]); } return 0; }
1. 基本思想:
每次循环的时候,找出数组中最小的元素,并且与循环操作中数组最前面的元素进行交换。流程图如下:
2. 代码清单:
void selectionSort(int *a, int length) { int outer, inner, min; for (outer = 0; outer < length - 1; outer++) { min = outer; for (inner = outer + 1; inner < length; inner++) { if (a[inner] < a[min]) { min = inner; } } int temp = a[outer]; a[outer] = a[min]; a[min] = temp; } } int main(int argc, const char * argv[]) { int a[] = {2, 4, 9, 1, 0, 3}; selectionSort(a, 6); for (int i = 0; i < 6; i++) { printf("%d\n", a[i]); } return 0; }
1. 基本思想:
每次假定数组第一个元素为在正确的位置上面,然后在数组后面依次寻找比这个元素大得并且是最小的那个元素,将其插入到指定元素的后面,与此同时,那些原本紧挨着指定元素后面的所有元素,依次往后移动一个位置。
2. 代码清单:
void insertSort(int *a, int length) { int i, j, target; // 假定第一个元素被放到了正确的位置上,这样仅需要便利n-1次 for (i = 1; i < length; i++) { j = i; target = a[i]; while (j > 0 && target < a[j - 1]) { a[j] = a[j - 1]; j--; } a[j] = target; } } int main(int argc, const char * argv[]) { int a[] = {4, 2, 6, 1, 8, 3}; insertSort(a, 6); for (int i = 0; i < 6; i++) { printf("%d\t", a[i]); } return 0; }
1. 基本思想:
将一个数组分解成多个数组,依次对每个子数组进行排序,最终将排序完成的子数组合并,进行最终的排序。
2. 代码清单:
void merge(int a[], int p, int q, int r) { int i, j, k, n1, n2; // 变量用于申请两个内存空间 int *front, *back; // 前一部分长度 n1 = q - p + 1; // 后一部分长度 n2 = r - q; // 申请两个空间存放拍好的数组 front = (int *)malloc(n1 * sizeof(int)); back = (int *)malloc(n2 * sizeof(int)); // 将数组转入两个新空间中 for (int i = 0; i < n1; i++) { front[i] = a[p + i]; } for (int i = 0; i < n2; i++) { back[i] = a[q + i + 1]; } // 将元素合并 i = 0; j = 0; k = p; while (i < n1 && j < n2) { if (front[i] < back[j]) { a[k++] = front[i++]; } else { a[k++] = back[j++]; } } // 将剩余元素合并 while (i < n1) { a[k++] = front[i++]; } while (j < n2) { a[k++] = back[j++]; } } void marge_sort(int a[], int p, int r) { int q; if (p < r) { q = (p + r) / 2; marge_sort(a, p, q); marge_sort(a, q + 1, r); merge(a, p, q, r); } } int main(int argc, const char * argv[]) { int a[8] = {1, 6, 4, 5, 3, 9, 7, 8}; marge_sort(a, 0, 7); for (int i = 0; i < 8; i++) { printf("%d\t", a[i]); } return 0; }
1. 基本思想:
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
6
|
2
|
7
|
3
|
8
|
9
|
下标
|
0
|
1
|
2
|
3 |
4
|
5
|
数据
|
3
|
2
|
7
|
6
|
8
|
9
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
下标
|
0
|
1
|
2
|
3
|
4
|
5
|
数据
|
3
|
2
|
6
|
7
|
8
|
9
|
void sort(int *a, int left, int right) { // 表示一组排序结束 if (left > right) { return; } int i = left; int j = right; int key = a[left]; while (i < j) { // 找到比key小的值,交换位置(放在左边) while (i < j && key <= a[j]) { j--; } a[i] = a[j]; // 找到比key大的值,交换位置(放在右边) while (i < j && key >= a[i]) { i++; } a[j] = a[i]; } a[i] = key; // 递归执行 sort(a, left, i - 1); sort(a, i + 1, right); } int main(int argc, const char * argv[]) { int a[] = {3, 5, 8, 1, 0, 2}; sort(a, 0, 5); for (int i = 0; i < 6; i++) { printf("%d\t", a[i]); } return 0; }