冒泡排序
遍历数组,通过两两交换;每次最大的数到最后面
进行arr.length-1次
每次循环,让数两两比较,内层循环长度递减,
如果数组里面没有交换位置,说明已经有序,停止比较
//冒泡排序 public static int[] sort2(int [] num){ boolean flag=false; for(int i=0;i<num.length-1;i++){ for(int j=0;j<num.length-1-i;j++){ if(num[j]>num[j+1]){ int temp=num[j]; num[j]=num[j+1]; num[j+1]=temp; flag=true; } } if(!flag){ break; } } return num; }插入排序
遍历arr.lenght-1次,将数插入进去
拿到的第一个数是有序的,每遍历无序区域的一个数,
拿到一个数,用一个变量存储,避免后面移动时数被覆盖
然后用这个数从后往前和已经有序的数作比较有序区域的数字比要插入数字大就往后移动一位,有序区域扩展一位,
遇到小于或者等于这个待插入数字时,就不在移动,这时指针指向的数是小于或者等于待插入数的下标
让待插入数字在这个数的后面
public static int[] sort1(int [] num){ for(int i=1;i<num.length;i++){ int temp=num[i];//无序的第一个数 int j=i-1;//无序的最后一个数就在有序第一个数的前面 while(num[j]>temp) { num[j+1]=num[j]; j--; } num[j+1]=temp; } return num; }选择排序
数组时无序的,让数组的最小的数和数组的第一个数交换,
剩下的最小的数和第二个数交换,剩下的第三小的,以此类推
循环arr.length-1次数,让数字排到前面,循环剩下的数,找到最小的数所在的下标,
每次把第一个数作为最小的数,
是通过每次找到最小的数的下标,让这个下标所在位置和数和数组第一个位置的数交换
public static int[] sort3(int [] num){ for(int i=0;i<num.length-1;i++){ int f=i;//每次那数组的第一个数作为用来作比较的数 for(int j=i+1;j<num.length;j++){ if(num[j]<num[f]){ f=j; }//不需要知道数字,只需要知道数组最小的数所在的下标 } int t=num[i]; num[i]=num[f]; num[f]=t; } return num; }三种算法的时间复杂度空间复杂度比较
排序算法 | 最好时间复杂度 | 最坏时间复杂度 | 平均时间复杂度 | 空间复杂度 | 稳定性 |
|---|---|---|---|---|---|
冒泡排序 | O(n) | O(n²) | O(n²) | O(1) | 稳定 |
插入排序 | O(n) | O(n²) | O(n²) | O(1) | 稳定 |
选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |
1. 冒泡排序(Bubble Sort)
最好:数组已经有序→ 只遍历 1 轮 →O(n)
最坏 / 平均:逆序 →O(n²)
空间:只用了临时变量 →O(1)
稳定(相同值不交换位置)
2. 插入排序(Insertion Sort)
最好:数组已经有序→ 每个数只需比较 1 次 →O(n)
最坏 / 平均:逆序 →O(n²)
空间:O(1)
稳定
实际比冒泡快很多(移动少,赋值比交换快)
3. 选择排序(Selection Sort)
最好 = 最坏 = 平均 = O (n²)无论你有序无序,每次都要找最小值,跑不掉
空间:O(1)
不稳定(会打乱相同元素顺序)