常见排序算法
名称 | 复杂度 | 说明 | 备注 |
冒泡排序 BubbleSort | O(N*N) |
将待排序的元素看作是竖着排列的 “ 气泡 ” ,较小的元素比较轻,从而要往上浮 |
|
插入排序 InsertionSort | O(N*N) | 逐一取出元素,在已经排序的元素序列中从后向前扫描,放到适当的位置 | 起初,已经排序的元素序列为空 |
选择排序 SelcetionSort | O(N*N) | 首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此递归。 |
|
快速排序 QuickSort | O(n*log2 (n)) | 先选择中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(递归)。 |
|
堆排序 HeapSort | O(n*log2 (n)) |
利用堆( heaps )这种数据结构来构造的一种排序算法。堆是一个近似完全二叉树结构,并同时满足堆属性:即子节点的键值或索引总是小于(或者大于)它的父节点。 |
近似完全二叉树 |
希尔排序 ShellSort |
O(n1+ £ ) 0< £ <1 |
选择一个步长 (Step) , 然后按间隔为步长的单元进行排序 . 递归 , 步长逐渐变小 , 直至为 1. |
|
箱排序 BinSort | O(n) |
设置若干个箱子,把关键字等于 k 的记录全都装入到第 k 个箱子里 ( 分配 ) ,然后按序号依次将各非空的箱子首尾连接起来 ( 收集 ) 。 |
分配排序的一种:通过 " 分配 " 和 " 收集 " 过程来实现排序。 |
桶排序 BucketSort | O(n) |
桶排序的思想是把 [0 , 1) 划分为 n 个大小相同的子区间,每一子区间是一个桶。 |
分配排序的一种:通过 " 分配 " 和 " 收集 " 过程来实现排序。 |
冒泡排序
冒泡排序算法的思想:很简单,每次遍历完序列都把最大(小)的元素放在最前面,然后再对剩下的序列重复前面的一个过程,每次遍历完之后待排序序列就少一个元素,当待排序序列减小为只有一个元素的时候排序就结束了。因此,复杂度在最坏的情况下是O(N ^ 2)。
- public static void BubbleSort(int[] array){
- if(array==null || array.length==0){
- return;
- }
- int size = array.length;
- for(int i=0; i<size-1; i++){
- boolean hasSwap = false;
- for(int j=i+1; j<size; j++){
- if(array[j]<array[i]){
- // swap
- int temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- hasSwap = true;
- }
- if(!hasSwap){
- break;
- }
- }
- }
- }
选择排序
选择排序(Selection Sort)的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕。
- public static void SelectionSort(int[] array){
- if(array==null || array.length==0){
- return;
- }
- int size = array.length;
- for(int i=0; i<size-1; i++){
- int minIndex = i;
- for(int j=i+1; j<size; j++){
- if(array[j]<array[minIndex]){
- minIndex = j;
- }
- }
- // 将最小值置于最前端
- if(minIndex!=i){
- int temp = array[minIndex];
- array[minIndex] = array[i];
- array[i] = temp;
- }
- }
- }
*与冒泡排序的区别,交换次数。每次遍历找到最小值,只交换一次。冒泡是每次比较都进行交换。
插入排序
插入排序是最简单最直观的排序算法了,它的依据是:遍历到第N个元素的时候前面的N-1个元素已经是排序好的了,那么就查找前面的N-1个元素把这第N个元素放在合适的位置,如此下去直到遍历完序列的元素为止。
算法的复杂度也是简单的,排序第一个需要1的复杂度,排序第二个需要2的复杂度,因此整个的复杂度就是1 + 2 + 3 + …… + N = O(N ^ 2)的复杂度。
算法的复杂度也是简单的,排序第一个需要1的复杂度,排序第二个需要2的复杂度,因此整个的复杂度就是1 + 2 + 3 + …… + N = O(N ^ 2)的复杂度。
- public static void InsertionSort(int[] array){
- if(array==null || array.length==0){
- return;
- }
- int size = array.length;
- // 默认认为第一位是有序的
- for(int i=1; i<size; i++){
- int key = array[i];
- // 对有序列从后向前扫描
- int j=0;
- for(j=i-1; j>=0; j--){
- if(key<array[j]){
- array[j+1] = array[j];
- }else{
- break;
- }
- }
- array[j+1] = key;
- }
- }
希尔排序
shell排序是对插入排序的一个改装,它每次排序把序列的元素按照某个增量分成几个子序列,对这几个子序列进行插入排序,然后不断的缩小增量
扩大每个子序列的元素数量,直到增量为一的时候子序列就和原先的待排列序列一样了,此时只需要做少量的比较和移动就可以完成对序列的排序了。
- public static void ShellSort(int array[])
- {
- if(array==null || array.length==0){
- return;
- }
- int temp;
- int size = array.length;
- // 增量从数组长度的一半开始,每次减小一倍
- for (int increment = size / 2; increment > 0; increment /= 2)
- {
- for (int i = increment; i < size; ++i)
- {
- temp = array[i];
- // 对一组增量为increment的元素进行插入排序
- int j = 0;
- for (j = i; j >= increment; j -= increment)
- {
- // 把i之前大于array[i]的数据向后移动
- if (temp < array[j - increment])
- {
- array[j] = array[j - increment];
- } else
- {
- break;
- }
- }
- // 在合适位置安放当前元素
- array[j] = temp;
- }
- }
- }
快速排序
快速排序的算法思想: 选定一个枢轴元素,对待排序序列进行分割,分割之后的序列一个部分小于枢轴元素,一个部分大于枢轴元素,再对这两个分割好的子序列进行上述的过程。
- public static void QuickSort(int[] array, int low, int hight){
- if(array==null || array.length==0){
- return;
- }
- if(low<hight){
- int n = Partition(array, low, hight);
- QuickSort(array, 0, n);
- QuickSort(array, n+1, hight);
- }
- }
- // 对一个给定范围的子序列选定一个枢纽元素,执行完函数之后返回分割元素所在的位置,
- // 在分割元素之前的元素都小于枢纽元素,在它后面的元素都大于这个元素
- private static int Partition(int[] array, int low, int hight){
- // 采用子序列的第一个元素为枢纽元素
- int pivot = array[low];
- int temp = 0;
- while(low<hight){
- // 从后往前在后半部分中寻找第一个小于枢纽元素的元素
- while(low<hight && array[hight]>=pivot){
- hight--;
- }
- // 将这个比枢纽元素小的元素交换到前半部分
- temp = array[low];
- array[low] = array[hight];
- array[hight] = pivot;
- // 从前往后在前半部分中寻找第一个大于枢纽元素的元素
- while(low<hight && array[low]<=pivot){
- low++;
- }
- // 将这个比枢纽元素大的元素交换到后半部分
- temp = array[low];
- array[low] = array[hight];
- array[hight] = temp;
- }
- // 返回枢纽元素所在的位置
- return low;
- }
来源:http://univasity.iteye.com/blog/1164713
微信公众号:
猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。