1、算法复杂度
2、稳定性
3、适用场景
4、对应的Java代码
分析来源:以下面几个排序为例
一、冒泡排序
特点:简单的排序算法;它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次比较相邻两个数的大小;判定--如果前者比后者大,则交换它们的位置(升序)。这样一次遍历之后,最大的元素在数列末尾!循环--采用相同的方法再次遍历时,第二大元素被排列在最大元素之前。目标--重复此操作,直到整个数列都有序为止!
理解:冒泡(由于气压原因,相邻的两个气泡,后者比前者大);遍历若干次(得到最终结果需要重复执行多次);
Java代码--以函数的形式(优化)--优化
package sort;
import java.util.Random;
public class Bubbling {
public static void main(String[] args) {
bubling();
}
private static void bubling() {
Random rd = new Random();// Random普通的类(不是工具类)
// 测试:函数的形式
int[] array = new int[10];
// 随机产生整数
for (int i = 0; i < array.length; i++) {
array[i] = rd.nextInt(100);// [0,100)
// 遍历结果
System.out.print(array[i] + " ");
}
System.out.println();
for (int i = array.length - 1; i > 0; i--) { //每次都是确定最后一个
// 定义标示位--每次遍历(一趟)都可能发生变化
boolean flag = true;
// 开始进行一次排序
for (int j = 0; j < i; j++) {
int temp = 0;// 临时变量
// 体现相邻
if (array[j] > array[j + 1]) {
// 互换位置--三种方式(最常用的)
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
// 交换位置说明次序变化了(只要有一次就OK)
flag = false;
}
}
// 若无交换,说明数据已经有序,直接跳出冒泡排序算法
if (flag == true) {
break;
}
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}
时间复杂度:O(n^2);理解--被排序的数列中有n个数。遍历一趟的算法复杂度为O(n),需要遍历(n-1)次!因此,冒泡排序的时间复杂度为O(n^2)
算法的稳定性:稳定
算法稳定性的解释:一个数列中有两个相等的数a[i]=a[j],在排序前,a[i]在a[j]前面,经过排序后a[i]仍然在a[j]前,排序算法稳定
思考:如果是降序呢?--简单修改
二、选择排序
基本思想:起始--在未排序的数列中找到最大(小)值,然后将其存放到数列的起始位置;过程--接着再从剩余未排序的元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。目标--以此类推,直到所有的元素均排序完毕
注意:并未提到相邻的元素
代码
package sort;
import java.util.Random;
public class Select {
public static void main(String[] args) {
select();
}
private static void select() {
//产生数据
Random rd = new Random();
int [] array=new int[20];
for(int i=0;i<array.length;i++){
array[i]=rd.nextInt(20);
System.out.print(array[i]+" ");
}
System.out.println();
//升序排列(注意一些细节)--只剩最后一个则无需排序了,所以是array.length-1
for(int i=0;i<array.length-1;i++){
for(int j=i+1;j<array.length;j++){
//比较,互换位置
int temp=0;
if(array[i]>array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
//查看结果
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
时间复杂度:O(n^2);理解--被排序的数列中有n个数,遍历一趟的算法复杂度为O(n),需要遍历(n-1)次!因此,冒泡排序的时间
复杂度为O(n^2)。
算法的稳定性:稳定
思考:降序呢?
三、快速排序
基本思想:使用分冶法策略;选择一个基数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据比另外一部分的所有数据都要小。然后,再按此方法对这两部分的数据进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
分冶法的思想:点击打开链接
一次排序的图解:
一次排序的过程:
1)设置两个变量(指针)i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为基准点(一般),注意:基准元素会影响 算法的效率
3)从j开始向前搜索,即由后开始向前搜索(j - -),找到第一个小于A[i](此时基准点)的值A[j],将A[i]与A[j]交换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于A[j](此时基准点)的值A[i],将A[j]与A[i]交换;
5)重复第3步
6)重复第3、4、5步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[j]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束),到此找到基准点的下标,作为分治下标
7)重复1-6步骤递归排序前半部分
8 ) 重复1-6步骤递归排序后半部分
算法的实现
Java递归:点击打开链接--第一种方法的问题(没有进行判断)