冒泡排序
排序原理:
- 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置。
- 对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值。
public static void main(String[] args) {
int arr[] = {4,2,5,3,1,6};
for (int i = arr.length-1; i > 0; i--){
for (int j = 0; j < i; j++){
if (arr[j]<arr[j+1]){
int temp;
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
注意事项:for循环的两个参数的边界情况,注意不要索引越界异常
时间复杂度:分为比较和交换两个步骤,且是嵌套在一起的,所以时间复杂度为O(n^2)
选择排序
排序原理:
- 每一次遍历的过程中,都假定第一个索引处的元素是最小值,和其他索引处的值依次进行比较,如果当前索引处的值大于其他某个索引处的值,则假定其他某个索引出的值为最小值,最后可以找到最小值所在的索引
- 交换第一个索引处和最小值所在的索引处的值
public static void main(String[] args) {
int arr[]={4,3,6,5,2,7,8,1};
for (int i = 0; i < arr.length-1; i++) {
//记录最小值的索引
int index = i;
for (int j = i+1; j<arr.length; j++){
if (arr[index]>arr[j]){
index = j;
}
}
int tem = arr[i];
arr[i] = arr[index];
arr[index] = tem;
}
System.out.println(Arrays.toString(arr));
}
时间复杂度:同冒泡排序一样,都是比较和交换的嵌套,故O(n^2)
插入排序
排序原理:
- 把所有的元素分为两组,已经排序的和未排序的;
- 找到未排序的组中的第一个元素,向已经排序的组中进行插入;
- 倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位;
public static void main(String[] args) {
int arr[] = {4,5,6,3,2,1,10,8};
for (int i=1; i<arr.length; i++){
for (int j=i; j>0; j--){
if (arr[j]<arr[j-1]){
int temp;
temp=arr[j-1];
arr[j-1]=arr[j];
arr[j]=temp;
}else {
// 只比前一个即可,因为前面是已排序部分
break;
}
}
}
System.out.println(Arrays.toString(arr));
}
时间复杂度:同理为O(n^2)
总结
冒泡排序与选择排序的区别:冒泡排序是相邻之间比较,比较完之后就交换,而选择排序是比较之后记录下最值的索引,最后直接与一开始索引处的交换。
冒泡排序和插入排序都是在比较之后就决定要不要进行交换,而选择排序是一轮比较结束之后再进行交换。
插入排序:就像是打扑克时的清牌动作,一直从后面抽牌往前插。
三个排序都是通过双重for循环实现,时间复杂度都同样为O(n^2)。