非线性时间比较排序:通过比较来决定元素之间的相对次序,由于其时间复杂度不能突破O(nlogn)。
线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下届,以线性时间运行。
非线性时间比较类排序
交换排序:冒泡;快排;
插入排序:简单插入排序;shell;
选择排序:简单选择;堆排序;
归并排序:二路归并;多路归并;
线性时间比较类排序
基数排序;桶排序;基数排序;
稳定性:排序后相对顺序不变;
不稳定性:排序后相对位置改变
时间复杂度:
空间复杂度:
算法复杂度
排序算法 | 平均时间复杂度 | 最好时间复杂度 | 最差时间复杂度 | 空间复杂度 | 稳定性 |
冒泡排序 | ![]() |
![]() |
![]() |
![]() |
稳定 |
快速排序 | ![]() |
![]() |
![]() |
![]() |
不稳定 |
简单选择 | ![]() |
![]() |
![]() |
![]() |
不稳定 |
堆排序 | ![]() |
![]() |
![]() |
![]() |
不稳定 |
简单插入 | ![]() |
![]() |
![]() |
![]() |
稳定 |
shell排序 | ![]() |
![]() |
![]() |
![]() |
不稳定 |
归并排序 | ![]() |
![]() |
![]() |
![]() |
稳定 |
1、冒泡排序
算法思想:重复走访要排序的数列,一次比较两个元素,如果它们的顺序错误就将它们交换过来,走访数列的工作是重复的进行指导没有再需要交换,即数列已经排序完成。
算法描述:
比较相邻的元素,如果第一个比第二个大,就交换它们两个。
对每一对相邻元素做相同的工作,从开始第一对到结尾的最后一对,这样在最后的元素就是最大的数。
针对所有元素重复以上步骤,对已经排序的元素不再进行排序,重复,直至排序完成。
public class BubbleSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr= new int[] {2,9,0,5,3,8,4};
bubblesort(arr);
for(int i=0;iarr[j+1]) {
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
}
选择排序
算法思想:首先在未排序序列中找到最小(大)的元素,存放在排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放在已排序序列的末尾,以此类推,直到所有元素都排序完毕。
算法描述
初始状态:无序区为R[1..n],有序区为空;
第i趟排序(i=1,2,....n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R[i...n],然后从无序区选取值最小的元素为R[k],将它与无序区的第一个记录R[i]交换,这样有序区就变成了R[1....i],无序区为R[i+1,.....n]
重复n-1趟,数组有序化
public static void selectsort(int[] arr) {
int len = arr.length;
for(int i=0;i
插入排序
算法思想:对数组中的每一个元素,在已排序序列中从后向前扫描,查找到相应的位置后插入。
算法描述:
从第一个元素开始,该元素已经排好序;
取出下一个元素,在已经排好序的序列中从后向前扫描;
如果该元素(已排序)大于新元素,该元素移动到下一个位置;
重复,直到找到已排序的元素小于等于新元素的位置;
将新元素插入到该位置后。
public static void insertsort(int[] arr) {
int len=arr.length;
for(int i=1;i0;j--) {
if (arr[i]index;j--) {
arr[j]=arr[j-1];
}
arr[index]=temp;
}
}
4、希尔排序(shell)
算法思想:缩小增量排序
算法描述:
选择一个增量序列t1、t2、......tk,其中ti>tj(i 按增量序列个数k,对序列进行k趟排序 每趟排序,根据对应的增量ti,将序列分割成若干个长度为m的子序列,分别对各子表进行直接插入排序,当增量因子为1时,整个序列作为一个表来处理,表长度为整个序列的长度。 5、快速排序 算法思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 算法描述: 从数据中挑出一个元素作为基准(pivot);(每次选择分区中最左边的元素作为基准) 重新排序数组,所有比基准值小的放在基准前面,所有比基准值大的元素放在基准元素后面,在这个分区退出之后,该基准就位于正确地位置上; 递归的把小于基准值元素的子数列和大于基准值元素的子数列排序; 6、堆排序 算法思想:利用堆这一数据结构所设计的一种排序算法,堆是一个近似完全二叉树的结构,并满足堆的性质,即结点的键值或者索引总是小于(或者大于)它的父结点。 算法描述: 1、将待排序列初始化为最大堆,并将堆顶元素R[1]删除,和最后一个元素R[n]进行交换; 2、将新的堆调整为最大堆,并重复操作1,直到整个排序过程完成; public static void quicksort(int[] arr,int left,int right) {
if (left>right) {
return;
}
int i=left,j=right;
int temp=arr[left];
while(i!=j) {
while (i
private static void buildMaxHeap(int[] arr,int len) {//建立最大堆
for(int i=len/2;i>=0;i--) {
heapify(arr,i,len);
}
}
private static void heapify(int[] arr,int i,int len) {//调整堆
int left=2*i+1;
int right=2*i+2;
int largest = i;
if (left