排序算法总结
#include <iostream> #include <list> #include <sstream> #include <map> #include <set> #include <queue> #include <map> #include <functional> #include <algorithm> #include <stack> #include <ctime> using namespace std; //冒泡排序(n2) //相邻元素交换,未交换结束,每次减1 void buble_sort(int a[], int n) { bool flag; do { flag = false; for (int j = 1; j < n; j++) { if (a[j - 1]>a[j]) { swap(a[j], a[j - 1]); flag = true; } } n--; } while (flag); } //插入排序,有序序列和无序序列,o(n*2),稳定 //从1开始依次和前面的有序序列相比,找到合适的插入位置插入 void insert_sort(int a[], int n) { int t,i,j; for (i = 1; i < n;i++) { t = a[i];//要插入的位置 for (j = i; j>0&&a[j-1]>t;j--) { a[j] = a[j - 1]; } a[j] = t; } } //选择排序,选择最小(不稳定) ,o(n*2) //3 7 4 2 void select_sort(int a[], int n) { for (int i = 0; i < n;i++) { int min = i; for (int j = i + 1; j < n; j++) { if (a[j] < a[min]) min = j; } if (min != i) swap(a[i],a[min]); } } //快速排序思路,找分界值,一般用中间得数据作为分界值,和第一个元素交换作为界,O (nlogn) //分组,比分界值小的在一边,比分界值大的在一边 //1.从左向右找,比分界值大的停下(避免走出右边界) //2.从右向左找,比分界值小的停下(避免走出左边界) //3, 交换 //如果分界值比,左右相遇的的值大,交换 //递归左边分组 //递归右边分组 //递归结束条件,元素个数不超过一个 void quick_sort(int a[], int n) { if (n <= 1) return; if (n == 2) { swap(a[0], a[1]); return; } swap(a[n / 2], a[0]); int jie = a[0]; int* L = a + 1; int* R = a + n - 1; while (L<R) { while (L < R&&*L < jie) L++; while (a<R&&*R>=jie) R--; if (L < R) swap(*L,*R); } if (*R<jie) { swap(a[0], *R); } quick_sort(a,R-a); quick_sort(R + 1, (n - 1) - (R - a)); } /**************************** 排序规则 **************************** 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序; 随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰 被分成一组,算法便终止。 稳定性: 希尔排序是非稳定排序算法。 *****************************************************************/ //希尔排序O(n^(1.3—2)) void shellSort(int *array, int len) { // 步长 int gap = len; while (gap > 1) { // 步长递减公式 gap = gap / 3 + 1; // 分组, 对每一组, 进行插入排序 for (int i = 0; i < gap; ++i) { int tmp; // 基准数 int index; // 坑的位置 // 插入排序 // 无序序列 for (int j = i + gap; j < len; j += gap) { tmp = array[j]; index = j; // 有序序列(从后往前遍历) for (int k = j - gap; k >= 0; k -= gap) { if (tmp < array[k]) { // 后移 array[k + gap] = array[k]; // 位置 index = k; } else { break; } } // 填坑 array[index] = tmp; } } } } //分组加插入排序 void shell_sort2(int a[],int n) { int gap = n,k=0,i=0,j=0; while (gap>1) { gap= gap / 3 + 1; for ( i = 0; i < gap;i++) { for (j = i+gap; j < n;j+=gap) { int t = a[j]; for ( k = j ; k > 0&&a[k-gap]>t;k-=gap) { a[k] = a[k - gap]; } a[k] = t; } } } } //归并排序o(nlogn),稳定 //将两个有序数列a[first...mid]和a[mid+1...last]合并。 void mergeArray(int a[], int first, int mid, int last, int temp[]) { int i = first; // 第一个有序序列的开始下标 int j = mid + 1; // 第2个有序序列的开始下标 int length = 0; // 合并两个有序序列 while (i <= mid && j <= last) { // 找二者中比较小的数 if (a[i] < a[j]) { temp[length] = a[i]; i++; } else { temp[length] = a[j]; j++; } length++; } // 还剩下一个有序序列中有数据 while (i <= mid) { temp[length] = a[i]; i++; length++; } while (j <= last) { temp[length++] = a[j++]; } // 覆盖原来位置的无序序列 for (int i = 0; i < length; ++i) { // 找到原来 的第一个有序序列的开始位置 - 开始覆盖 a[first + i] = temp[i]; } } //归并排序 void mergeSort(int a[], int first, int last, int temp[]) { // 递归结束的条件 if (first == last) { return; } // 从中间位置拆分 int mid = (first + last) / 2; // 拆分 // 左半边 mergeSort(a, first, mid, temp); // 右半边 mergeSort(a, mid + 1, last, temp); // 合并两个有序序列 mergeArray(a, first, mid, last, temp); } #define N 65530 int main() { int a[N]; for (int i = N; i > 0;i--) { a[N - i] = i; } int*p = (int*)malloc(sizeof(int)*N); clock_t t1 = clock(); mergy_sort2(a, 0,N-1,p); clock_t t2 = clock(); cout << "time:"<<double(t1 - t2) / CLOCKS_PER_SEC << endl; for (int i = 0; i < 10;i++) { cout << a[i] << " "; } cout << endl; free(p); system("pause"); }