排序算法分为两大类:内排序与外排序。内排序为数据都存储在ram中进行的排序。外排序需要将中间生成的数据保存到硬盘等设备上。
内排序分为如下5大类:
(1)、插入排序:直接插入排序、二分法插入排序、希尔排序。
(2)、选择排序:简单选择排序、堆排序。
(3)、交换排序:冒泡排序、快速排序。
(4)、归并排序
(5)、基数排序
1. 插入排序(直接插入排序)
将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:设立哨兵,作为临时存储和判断数组边界之用
#include <iostream> using namespace std; void insertSort(int a[], int n); void debug_print(int a[], int n); int main() { int data[]={7,4,6,3,2,12,32,98,2432,345,2234,1,54,23}; int n = sizeof(data)/sizeof(int); cout << n << endl; insertSort(data, n); debug_print(data, n); return 0; } void debug_print(int a[], int n) { for (int i = 0; i < (n-1); i++) { cout << a[i] << " "; } cout << endl; } void insertSort(int a[], int n) { int tmp = 0; debug_print(a, n); for (int i = 1; i < (n - 1); i++) { int j = i -1; tmp = a[i]; if (tmp < a[i-1]) { while((j > -1) && (tmp < a[j])) { a[j+1] = a[j]; j--; } cout << j << " " <<tmp << endl; a[j+1] = tmp; } debug_print(a, n); } }
2. 插入排序(希尔排序)
希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序
基本思想:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
操作方法:
选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
按增量序列个数k,对序列进行k 趟排序;
每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长
度即为整个序列的长度。
代码实现:
#include <iostream> using namespace std; void insert_sort(int a[], int n, int k); void shell_sort(int a[], int n); void debug_print(int a[], int n); int main() { int data[] = {49, 38, 65, 97, 76, 13, 27, 49, 55, 04}; //int data[] = {12,23,1,9,8,123,234,100, 101}; int n = sizeof(data)/sizeof(int); debug_print(data, n); // insert_sort(data, n, 1); shell_sort(data, n); debug_print(data, n); return 0; } void debug_print(int a[], int n) { cout << "["; for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << "]"; cout << endl; } void insert_sort(int a[], int n, int k) { int tmp = 0; for (int i = k; i < n; i++) { int j = i - k; tmp = a[i]; if (a[i] < a[i-k]) { while ((j > -1) && (tmp < a[j])) { a[j+k] = a[j]; j-=k; } a[j+k] = tmp; } debug_print(a, n); } } void shellsort_debug_print(int a[], int n, int factor) { cout << "factor: " << factor << " ["; for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << "]"; cout << endl; } void shell_sort(int a[], int n) { int factor = n/2; while (factor >= 1) { insert_sort(a, n, factor); shellsort_debug_print(a, n, factor); factor = (factor / 2); } }
3. 插入排序(二分查找法排序)
基本思想:二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。
代码实现:
#include <iostream> using namespace std; void debug_print(int a[], int n); void binary_insert_sort(int a[], int n); int main() { int data[] = {89,34,67,87,23,1,8,10,4}; int n = sizeof(data)/sizeof(int); binary_insert_sort(data, n); debug_print(data, n); return 0; } void debug_print(int a[], int n) { cout << "["; for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << "]"; cout << endl; } void binary_insert_sort(int a[], int n) { for (int i = 1; i < n; i++) { int j = i - 1; int tmp = a[i]; int low = 0; int high = i - 1; int mid = 0; if (tmp < a[i-1]) { while (low <= high) { mid = (low + high) / 2; if (tmp < a[mid]) high = mid - 1; else low = mid + 1; } for (int m = (i - 1); m >= low; m--) { a[m+1] = a[m]; } if (low != i) a[low] = tmp; } } }
5. 选择排序(简单选择排序)
在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
代码实现:
#include <iostream> using namespace std; void debug_print(int a[], int n); void simple_select(int a[], int n); int main() { int data[] = {65, 34, 23, 45, 9, 5, 3, 12}; int n = sizeof(data) / sizeof(int); debug_print(data, n); simple_select(data, n); debug_print(data, n); return 0; } void debug_print(int a[], int n) { cout << "["; for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << "]" << endl; } void simple_select(int a[], int n) { int tmp = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (a[i] < a[j]) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } debug_print(a, n); } }