排序算法总结
最近秋招,遇到了好多排序算法的题目,这两天看了一些常用的排序算法,那就总结一下咯。(算法均由java实现)
参考文章点这里–排序算法总结
冒泡排序
从大一就开始冒泡了oO~
原理:
冒泡排序从本质上讲是一种交换值的排序,把“正确的值”和“错误的值”进行交换。为什么叫冒泡呢?想象一下每次都把较大的值往末端放,就好像一个泡泡慢慢往上浮。
趟数:n-1
每趟的过程:每次从最左边的数字开始,同它右边的数比较,如果比它大,则交换位置,直到和最后一个无序数比较完。
private static void bubbleSort(int[] arr){
int n=arr.length;//数组的长度
for(int i=0;i<n-1;i++){//需要经过n-1次趟排序
for(int j=0;j<n-i-1;j++){//每一趟排序的过程
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
特点:
- 简单,容易实现,这个应该算吧
最好的情况下(所有数字都是正序),可以一趟就结束。
看了上面的,是不是觉得有问题呢,确实哈,如果要实现第二个特点,则需要对冒泡排序进行优化。如果在某一趟排序的时候,没有任何的位置发生变动,那么就说明这个序列已经是有序的了,然后就可以跳出循环啦。这样的冒泡排序就是改进冒泡排序法。
要实现这种方法很简单,就是加一个标志位。
private static void upBubbleSort(int[] arr){
int n=arr.length;
boolean flag=true;//设定标志位,初始为true
for(int i=0;i<n-1;i++){
if(flag){//如果为true则进行下一趟排序
flag=false;//每一趟开始的时候把标志位设定为false
for(int j=0;j<n-i-1;j++){
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=true;//发生变动了就设置为true
}
}
}else{
break;
}
}
}
总结:
最坏时间:O(n^2)
最好时间:O(n)
平均时间:O(n^2)
稳定性:稳定
稳定性就是指排序算法在排序时,相同大小值的数是否会改变相对位置,如果不变,就是稳定的,相反,是不稳定的。
选择排序
选择排序也是一种很简单的排序
原理:
选择即挑选,每次从等待排序的数据元素里选出最小或者最大的元素,放到未拍好序部分的最左边。
趟数:n-1
每趟的过程:使用一个中间量min来记录最小数的下标,初始值为未排序的序列部分的第一个值。依次比较,如果min记录的元素的值大于比较值,则min的值变为比较值的下标。最后在这一趟结束的时候将最小值和未排序的最左值交换位置。(如果求最大值类似)
private static void selectSort(int[] arr){
int n=arr.length;
for(int i=0;i<n-1;i++){
int minIndex=i;//记录最小下标
for(int j=i;j<n-1;j++){
if(arr[minIndex]>arr[j+1]){
minIndex=j+1;
}
}
int temp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
特点
- 相对于冒泡排序的优势,一趟数据交换的次数只会是0或1。
总结
最坏时间:O(n^2)
最好时间:O(n^2)
平均时间:O(n^2)
稳定性:不稳定(比如,4,4,3。 3和4交换后两个4的相对顺序改变了)