标签:padding 使用 qsort 关系 break 数字 pad [] reset
给定NN个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:
输入第一行给出正整数NN(\le 10^5≤10?5??),随后一行给出NN个(长整型范围内的)整数,其间以空格分隔。
在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。
11
4 981 10 -17 0 -20 29 50 8 43 -5
-20 -17 -5 0 4 8 10 29 43 50 981
下面试验了各种排序算法的的表现
算法/时间复杂度 |
10^3的随机整数 |
10^4个随机整数 |
10^5个随机整数 |
10^5个顺序整数 |
10^5个逆序整数 |
10^5个基本有序的整数 |
10^5个随机正整数,每个数不超过1000 |
冒泡排序 |
4ms |
228ms |
>10s |
88ms |
>10s |
650ms |
>10s |
插入排序 |
3ms |
35ms |
4784ms |
82ms |
9206ms |
115ms |
4499ms |
选择排序 |
5ms |
332ms |
>10s |
>10s |
>10s |
>10s |
>10s |
归并排序(递归版本) |
4ms |
12ms |
131ms |
82ms |
127ms |
83ms |
75ms |
堆排序 |
3ms |
10ms |
103ms |
89ms |
102ms |
126ms |
94ms |
希尔排序 |
3ms |
25ms |
128ms |
119ms |
125ms |
117ms |
116ms |
归并排序(循环版本) |
3ms |
24ms |
125ms |
78ms |
99ms |
77ms |
93ms |
快速排序(pivot取中位数) |
3ms |
10ms |
122ms |
76ms |
112ms |
76ms |
69ms |
/* 冒泡排序 * 1.最好情况 已经有序了O(n) * 2.最坏情况 逆序 O(n^2) * 3.平均情况 O(n^2) */ void bubble_sort(int a[],int n) { for (int i = n - 1; i > 0; i--) { int flag = 0; for (int j = 0; j < i; j++) { if (a[j] > a[j + 1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; flag = 1; } } if (flag == 0) break; } }
/* * 插入排序(对于基本有序的数组排序有较好的表现) * 1.最好情况 有序 O(n) * 2.最坏情况 逆序 o(n^2) * 3.平均情况 O(n^2) */ void insertion_sort(int a[],int n) { int i, j; for (i = 1; i < n; i++) { int temp = a[i]; /* 当前要插入的数 */ for (j = i - 1; j >= 0; j--) { if (temp >= a[j]) break; a[j + 1] = a[j]; } a[j + 1] = temp; } }
/* * 希尔排序(不稳定) * 1.时间复杂度跟取得序列有关系 * 2.取 n/2,n/2^2,...,1序列时 最坏情况下时间复杂度为O(n^2) * 3.sedgewick序列时 最坏: O(n^3/2) 平均:O(n^5/4) */ void shell_sort(int a[],int n) { int i, j; int sedgewick[] = { 929,505,209,41,19,5,1,0 }; for (i = 0; sedgewick[i] >= n; i++); for(int d=sedgewick[i];d>0;d=sedgewick[++i]) for (int p = d; p < n; p++) { int temp = a[p]; for (j = p; j >= d&&a[j - d] > temp; j -= d) a[j] = a[j - d]; a[j] = temp; } }
/* * 选择排序(不稳定 应该是最差的排序算法了吧) * 最好 最坏 平均 时间复杂度都是O(n^2) */ void selection_sort(int a[],int n) { for (int i = 0; i < n-1; i++) { int min = i; for (int j = i + 1; j < n; j++) { if (a[j] < a[min]) { min = j; } } if (min != i) { int temp = a[min]; a[min] = a[i]; a[i] = temp; } } }
/* * 归并排序(递归版本) 在外排序中使用较多 * 1.时间复杂度 最好 最坏 平均 都是O(n*log n). * 2.空间复杂度 是 O(n). */ void merge1(int a[],int temp[],int left,int right,int rightEnd) { int l = left; int leftEnd = right -1; int r = right; int index = rightEnd - left + 1; int x = left; while (l <= leftEnd && r <= rightEnd) { if (a[l] <= a[r]) { temp[x++] = a[l++]; } else temp[x++] = a[r++]; } while (l <= leftEnd) temp[x++] = a[l++]; while (r <= rightEnd) temp[x++] = a[r++]; for (int i=rightEnd; index > 0; index--,i--) a[i] = temp[i]; } void mSort1(int a[],int temp[],int left,int right) { if (left < right) { int mid = (left + right) / 2; mSort1(a, temp, left, mid); mSort1(a, temp, mid + 1, right); merge1(a, temp, left, mid + 1, right); } } void merge_sort1(int a[],int n) { int* temp = (int*)malloc(sizeof(int)*n); if (temp != NULL ) { mSort1(a, temp, 0, n-1); free(temp); } else { cout << "内存不足" << endl; } }
/* * 归并排序循环版本 * 1. 时间复杂度 最好 最坏 平均 都为O(n * log n) * 2. 空间复杂度O(n) */ void merge2(int a[], int temp[], int left, int right, int rightEnd) { int l = left; int leftEnd = right - 1; int r = right; int index = rightEnd - left + 1; int x = left; while (l <= leftEnd && r <= rightEnd) { if (a[l] <= a[r]) { temp[x++] = a[l++]; } else temp[x++] = a[r++]; } while (l <= leftEnd) temp[x++] = a[l++]; while (r <= rightEnd) temp[x++] = a[r++]; } void mergePass(int a[],int temp[],int n,int length) { int i; for (i = 0; i + 2 * length <= n; i += 2 * length) { merge2(a, temp, i, i + length, i + 2 * length - 1); } if (i + length < n) { merge2(a, temp, i, i + length, n - 1); } else for (int j = i; j < n; j++) temp[j] = a[j]; } void merge_sort2(int a[],int n) { int* temp = (int*)malloc(n * sizeof(int)); if (temp != NULL) { int length = 1; while (length < n) { mergePass(a, temp, n, length); length *= 2; mergePass(temp, a, n, length); length *= 2; } free(temp); } else { cout << "内存不足" << endl; } }
/* * 堆排序(不稳定) * 最好 最坏 平均 时间复杂度 O(n*log n). */ void adjust(int a[],int i, int n) { int parent, child; int temp = a[i]; for (parent = i; parent * 2 < n - 1; parent = child) { child = parent * 2 + 1; /* 先指向左孩子 */ if (child != n - 1 && a[child+1] > a[child]) { child++; /* 右孩子较大则指向右孩子 */ } if (temp >= a[child]) break; else a[parent] = a[child]; } a[parent] = temp; } void heap_sort(int a[], int n) { for (int i = (n-1) / 2; i >= 0; i--) adjust(a,i,n); /* 构建最大堆 */ for (int i = n - 1; i > 0; i--) { int temp = a[i]; a[i] = a[0]; a[0] = temp; adjust(a, 0, i); } }
/* * 快速排序 (不稳定) * 1.最坏情况和主元的选取有一定的关系 如果选首位为主元O(n^2) * 2.最好 平均 O(n * log n) * 3.当待排元素较少时 快排效率会急速下降 此时可采用插入排序 */ void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int median3(int a[],int left,int right) { int center = (left + right) / 2; if (a[left] > a[center]) { swap(&a[left], &a[center]); } if (a[left] > a[right]) { swap(&a[left], &a[right]); } if (a[center] > a[right]) { swap(&a[center], &a[right]); } swap(&a[center], &a[right-1]); /* 将基准放在数组右端 */ return a[right-1]; } void qSort(int a[],int left,int right) { int cutoff = 100; int low, high, pivot; if (right - left >= cutoff) { pivot = median3(a, left, right); low = left; high = right - 1; while (1) { while (a[++low] < pivot); while (a[--high] > pivot); if (low < high) swap(&a[low], &a[high]); else break; } swap(&a[low], &a[right - 1]); qSort(a, left, low - 1); qSort(a, low + 1, right); } else insertion_sort(a+left,right-left+1); } void quick_sort(int a[],int n) { qSort(a,0,n-1); }
算法/时间复杂度 |
10^3的随机整数 |
10^4个随机整数 |
10^5个随机整数 |
10^5个顺序整数 |
10^5个逆序整数 |
10^5个基本有序的整数 |
10^5个随机正整数,每个数不超过1000 |
冒泡排序 |
4ms |
228ms |
>10s |
88ms |
>10s |
650ms |
>10s |
插入排序 |
3ms |
35ms |
4784ms |
82ms |
9206ms |
115ms |
4499ms |
选择排序 |
5ms |
332ms |
>10s |
>10s |
>10s |
>10s |
>10s |
归并排序(递归版本) |
4ms |
12ms |
131ms |
82ms |
127ms |
83ms |
75ms |
堆排序 |
3ms |
10ms |
103ms |
89ms |
102ms |
126ms |
94ms |
希尔排序 |
3ms |
25ms |
128ms |
119ms |
125ms |
117ms |
116ms |
归并排序(循环版本) |
3ms |
24ms |
125ms |
78ms |
99ms |
77ms |
93ms |
快速排序(pivot取中位数) |
3ms |
10ms |
122ms |
76ms |
112ms |
76ms |
69ms |
基数排序 |
|
|
|
|
|
|
标签:padding 使用 qsort 关系 break 数字 pad [] reset
原文地址:http://www.cnblogs.com/minesweeper/p/6145999.html