内部排序
来源:互联网 发布:ubuntu tty1 登录 编辑:程序博客网 时间:2024/05/12 19:55
排序算法的优劣指标:
时间复杂度:比较次数和移动次数
空间复杂度:需要多少辅助内存
稳定性:若A和B关键字相等,排序后先后次序没变则称之为稳定的,否则是不稳定的。
内部排序和外部排序:
需不需要辅助内存。
内部排序分类:选择排序(直接选择排序、堆排序) 交换排序(冒泡排序、快速排序) 插入排序(直接插入排序、折半插入排序、shell排序) 归并排序 桶式排序 基数排序。
选择排序:
直接选择排序:简单直观但性能略差。 (改进的选择排序先交换下标)
>public static void arraySelect(int[] a) { for (int out = 0; out < a.length - 1; out++) { int min = out; for (int in = out + 1; in < a.length; in++) { if (a[in] < a[min]) min = in; } if(min!=out){ int s0 = a[out]; a[out] = a[min]; a[min] = s0; } } }
思路:第一个数,从后面的数中依次比较得出最小者,与第一位交换。依次过去。 特点:排一次可以确定最左边的最小者。 从而out++。
时间复杂度为O(n2) 空间复杂度为O(1)。 直接选择排序不稳定。
堆排序:
从上至下、从左至右:小根堆(顶子树最小,左比右小)大根堆(顶子树最大,左比右大) 完全二叉树。
时间浮复杂度O(nlogn) 空间复杂度 O(1) 堆排序不稳定
交换排序:主体操作是对数据组中的数据不断进行交换操作。
冒泡排序:
public static void arrayBub(int[] a) { for(int out=a.length-1;out>1;out--){ for(int in=0;in<out;in++){ if(a[in]>a[in+1]){ int s=a[in+1]; a[in+1]=a[in]; a[in]=s; } } } }
思路:从左边开始,相邻两个比较,选出较小者放左边,依次过去。 特点:排一次可以确定最右边是最大者。 从而out-1.
时间效率不确定, 空间效率为O(1)。 冒泡排序稳定。快速排序:选取一个数作为分界值,比它小的放左边,大的放右边。 然后对左右两个子序列进行递归。
public void quickSort() { recQuickSort(0, nElems - 1); } private void recQuickSort(int left, int right) { if (right - left <= 0) { return; } else { long pivot = theArray[right]; int partition = partitionIt(left, right, pivot); recQuickSort(left, partition - 1); recQuickSort(partition + 1, right); } }
时间效率高 O(nlogn), 因为使用了递归,递归使用了栈,空间效率为O(nlog2n) 包含跳跃式交换,所以快速排序不稳定。
插入排序:
直接插入排序:
public static void arrayInsert(int[] a) { for (int out = 1; out < a.length; out++) { int temp = a[out]; int in = out; while (in > 0 && a[in - 1] >= temp) { a[in] = a[in - 1]; in--; } a[in] = temp; } }
思路:从第二个元素开始,保持前面的元素局部有序。out++角标右移,与前面局部有序的部分比较,然后插入。
特点:对于开始就比较有序的数组,插入排序算法很快; 但对于随机数组,插入排序很慢。 时间复杂度O(n2)折半插入排序:
public void halfInsert(){ for(int i=0;i<theArray.length;i++){ int tmp=(int) theArray[i]; int low=0; int high=i-1; while(low<=high){ int mid=(low+high)/2; if(tmp>=theArray[mid]){ low=mid+1; }else{ high=mid-1; } } for(int j=i;j>low;j--){ theArray[j]=theArray[j-1]; } theArray[low]=tmp; } }
折半插入排序可以更快的确定第i个元素的插入位置。 效果与简单插入排序的效果基本相同,只是更快一些。
shell排序:可以认为直接插入排序是shell排序的一种特例—直接使用增量为1的shell排序就是直接插入排序。
public void shellSort() { int inner, outer; long tmp; int h = 1; while (h <= nElems / 3) h = h * 3 + 1; while (h > 0) { for (outer = h; outer < nElems; outer++) { tmp = theArray[outer]; inner = outer; while (inner > h - 1 && theArray[inner - h] >= tmp) { theArray[inner] = theArray[inner - h]; inner -= h; } theArray[inner]=tmp; } h=(h-1)/3; } }
shell排序是直接插入排序的改进版,所以是稳定的,时间开销在 O(n3/2)~O(n7/6)之间。 空间开销是O(1)。
归并排序:
基本思想是将多个有序的序列合并成一个新的有序序列。
public void MergeSort() { sort(theArray, 0, nElems - 1); } private void sort(long[] theArray, int left, int rght) { int center = (left + rght) / 2; sort(theArray, left, center); sort(theArray, center + 1, rght); merge(theArray, left, center, rght); } private void merge(long[] theArray2, int left, int center, int rght) { long[] tmpArr = new long[theArray2.length]; int mid = center + 1; int third = left; int tmp = left; while (left <= center && mid <= rght) { if (theArray[left] <= theArray[mid]) { tmpArr[third++] = theArray[left++]; } else { tmpArr[third++] = theArray[mid++]; } } while (mid <= rght) { tmpArr[third++] = theArray[mid++]; } while (left <= center) { tmpArr[third++] = theArray[left++]; } while (tmp <= rght) { theArray[tmp] = tmpArr[tmp++]; } }}
归并算法需要递归地分解、合并,每进行一趟两路归并排序需要调用merge方法一次,每次执行merge方法需要比较n次,所以时间复杂度为O(nlog2n) ;空间效率较差,它需要一个与原始序列同样大小的辅助序列。 归并算法是稳定的。
桶式排序:
不是基于比较的算法。要求待排序满足:所有值处于一个可枚举范围内;枚举范围不应太大,否则开销太大。
基数排序:
必须依赖于另外的排序算法。总体思路将待排序的数据拆分成多个排序关键字。
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- 内部排序
- C++程序运行时间计算【网上摘抄,方便查询】
- Navicat for MySQL:快捷键整理
- Leetcode学习(16)—— Max Consecutive Ones
- PHP 使用MYSQLI扩展操作数据库
- 线程视图(并行性能)
- 内部排序
- 欢迎使用CSDN-markdown编辑器
- <Effective Mordern C++>Item 6:UseTheExplicitlyTypedInitializerIdiomWhenAutoDeducesUndesiredTypes
- [leetcode]: 350. Intersection of Two Arrays II
- PHP mysqli 预处理
- ionic入门之数据绑定显示-1
- matlab 内存不足
- 未来生活进行时: 畅想未来新兴技术40年——百大趋势性技术汇总(中)
- Java-String类的常用方法总结