排序算法总结(算法导论)
来源:互联网 发布:资本结构优化 编辑:程序博客网 时间:2024/06/01 08:25
排序算法是众多算法的基础,是实际工程中真正需要用到的算法之一。
在数据的组织中,排序因为能将数据变得有序,往往能带来访问效率的提高。另一方面,在有些时候,排序算法中前k大值等的求取本身就是直接需求。
数据hash算法是与排序相匹敌的另一类高效访问算法,效率高到O(1),但hash算法只能用于普通的插入查找,不能用于需要比较数值的情况,另一方面,对于小规模数据,hash算法的实际代码长度抵消了复杂度优势。
纸牌游戏中的插入排序通常是身边最能接触到的最简单排序算法,而堆排序则是一种稳定高效的排序算法。本文将由简入繁介绍相关的排序算法。
int sort_insertion(int* data, int n){ for (int i = 1; i<n; i++){ //insert data[i] into sorted array data[0:i-1]; int j = 0; int iv = data[i]; for (j = i-1; j >= 0 && data[j]>iv; j--){ data[j + 1] = data[j]; } data[j + 1] = iv; } return 0;}
这个算法原理是,依次将第 i 个数插入在 之前排好序的 i 大小的队列中,复杂度为 O(n^2)。
2、冒泡排序
int sort_up(int *data, int n){ for (int i = 0; i<n; i++){ for (int j = i + 1; j<n; j++){ if (data[i] > data[j]){ int temp = data[i]; data[i] = data[j]; data[j] = temp; } } } return 0;}
这个算法原理是将余下的数依次上翻两两比较,从而将最小的数浮到顶部。1和2的算法简单,适合于小规模数据,由于其代码简短的优点,即使复杂度为O(n^2),效率依然不错。
3、快速排序
int sort_quick(int *data, int p, int q){ if (p >= q){ return 0; } int sep = data[q]; int d = p - 1; for (int i = p; i<q; i++){ if (data[i] < sep){ d++; int temp = data[i]; data[i] = data[d]; data[d] = temp; } } d++; data[q] = data[d]; data[d] = sep; sort_quick(data, p, d - 1); sort_quick(data, d + 1, q); return 0;}
这个算法原理是用尾部数将数据分成大小两段,再分别递归。复杂度为 O(n logn),但是在极端情况下,比如数据已经排好序的情况下,复杂度退化为 O(n^2)。
4、计数排序
//k = max(data(n))int sort_count(int* data, int k, int n){ int *a = new int[k]; int *b = new int[n]; memset(a, 0, k*sizeof(int)); memset(b, 0, n*sizeof(int)); for (int i = 0; i < n; i++){ a[data[i]] ++; } for (int i = 1; i < k; i++){ a[i] = a[i - 1] + a[i]; } for (int i = n-1; i >= 0; i--){ b[a[data[i]]-1] = data[i]; a[data[i]]--; } memcpy(data, b, n*sizeof(int)); delete[]a; delete[]b; return 0;}
计数排序时间复杂度为O(k+n),因为他并不是比较排序算法,所以下界优于 O( nlogn )。一个优点,它是稳定的。一个缺点,它不是原地的。
5、基数排序
技术排序利用了计数排序稳定性的特点。
SORT_RADIX(A, d)for i<-1, d do use a stable sort to sort array A on digit i
基数排序时间复杂度为O(d*(n+k))。
6、桶排序
当数据的输入符合均匀分布时,可以以线性期望时间运行。
BUCKET_SORT(A, n) for i in 1 to n: do insert A[i] into list B[ |n*A[i]|下界 ] for i in 0 to n-1: do sort B[i] with insertion sort; concatenate the list B[0], B[1], ..., B[n-1] together in order
时间复杂度为O(n* (2-1/n)),即O(n).
7、归并排序
归并排序是一种分治合并策略。
int sort_merge(int *a, int p, int r){ if (p >= r){ return 0; } int q = (p + r + 1) / 2; int *b1 = new int[q - p + 1]; int *b2 = new int[r - q + 1 + 1]; memcpy(b1, a, (q - p)*sizeof(int)); memcpy(b2, a + q, (r - q + 1)*sizeof(int)); sort_merge(b1, 0, q - p - 1); sort_merge(b2, 0, r - q); b1[q - p] = b2[r - q + 1] = 0x7fffffff; for (int k = p, i = 0, j = 0; k <= r; k++){ if (b1[i] < b2[j]){ a[k] = b1[i]; i++; } else{ a[k] = b2[j]; j++; } } delete[]b1; delete[]b2; return 0;}
归并排序时间复杂度为O(nlogn)
8、堆排序
//a[1:n]int max_heap(int *a, int i, int n){ while (i < n){ if (a[i] < a[i * 2] && i * 2 == n){ swap(a[i], a[i * 2]); break; } else if (a[i] < a[i * 2] && i * 2 + 1 <= n && a[i * 2] >= a[i * 2 + 1]) { swap(a[i], a[i * 2]); i = i * 2; } else if (a[i]<a[i * 2 + 1] && i * 2 + 1 <= n && a[i * 2 + 1]>a[i * 2]){ swap (a[i], a[i * 2 + 1]); i = i * 2 + 1; } else{ break; } } return 0;}int bulid_max_heap(int *a, int n){ for (int i = n / 2; i >= 1; i--){ max_heap(a, i, n); } return 0;}int heap_sort(int *a, int n){ bulid_max_heap(a, n); for (int i = n; i >= 1; i--){ swap (a[i], a[1]); max_heap(a, 1, i - 1); } return 0;}
堆排序时间复杂度为O(nlogn)。
0 0
- 排序算法总结(算法导论)
- 【算法导论】排序算法总结
- 《算法导论》总结(一):线性时间排序算法
- 算法导论排序算法之最后总结(七)
- 算法导论中九大排序算法总结
- 算法导论—排序算法总结
- 《算法导论》排序算法
- 《算法导论》排序算法
- 【算法导论】排序(一)
- 堆排序(算法导论)
- 堆排序(算法导论)
- 快速排序(算法导论)
- 算法导论第六章 堆排序总结
- 算法导论第六章总结:堆排序
- 算法导论第七章总结:快速排序
- 学习《算法导论》第一章 插入排序 总结
- 算法导论22.4拓扑排序 练习总结
- 算法导论九大排序总结
- 归并排序、二分法查找的递归实现
- 秦殇 二进制txt 异或
- iOS基础面试题(一)
- makefile $@ $< $^ 自动化变量
- iOS基础面试题(二)
- 排序算法总结(算法导论)
- Spring架构学习(1)编码实现依赖注入
- SVN代码管理使用方法和注意事项
- iOS基础面试题(三)
- javascript初学者课程
- 在apache中隐藏php文件后缀
- 用免费radius软件实现设备AAA管理(转)
- Oracle单行函数 (二)
- iOS基础面试题(四)