一、排序的基本概念
1.排序的分类
升序(非降序):数据由小到大排列。(一般会默认)
降序(非升序):数据由大到小排列。
2.七大基于比较的排序
(1)插入类排序:直接插入排序和希尔排序。
(2)交换类排序:冒泡排序和快速排序。
(3)选择类排序:简单选择排序和堆排序。
(4)归并排序
3.稳定性
针对在待排序的序列中存在具有多个相同关键字的记录。设Ki=Kj,它们的下标分别是Ri和Rj。若在排序前Ri<Rj(即i<j),经过排序后Ri对应的元素仍然是Ki,则称所用的排序方法是稳定的。反之,若相同关键字的领先关系在排序过程中发生变化,则称所用的排序方法是不稳定的。
4.内部排序和外部排序
根据排序是数据所占用存储器的不同,可将排序分为两类。一类是整个排序过程完全在内存中进行,称为内部排序。另一类是由于待排序记录数据量太大,内存无法容纳全部数据,排序需要借助外部存储设备才能完成,称为外部排序。
二、冒泡排序(交换类排序)
1.升序
冒泡过程:两个相邻的数依次比较,较大的数放到后面。
减治算法:每次处理都减少一个数,剩下的数采用相同的方式处理。
用外层循环表示比较的轮数,内层循环控制比较次数和比较的数的下标。
2.降序
冒泡过程:两个相邻的数依次比较,较小的数放到后面。
也是一种减治算法。
优化:设置一个有序状态标记位,如果数列已经有序,则直接返回;否则继续下一轮比较。
public class BubbleSort {
private static void ascemdingBubbleSort(int[] array){
boolean isSortted=true;
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]>array[j+1]){
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
isSortted=false;
}
if(isSortted){
break;
}
}
}
}
private static void descendingBubbleSort(int[] array){
boolean isSortted=true;
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]<array[j+1]){
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
isSortted=false;
}
if(isSortted){
break;
}
}
}
}
public static void main(String[] args) {
int[] array=new int[]{10,8,5,33,12,1,4,2,5};
ascemdingBubbleSort(array);
System.out.print("升序为:");
for(int item:array){
System.out.print(item+" ");
}
System.out.println();
descendingBubbleSort(array);
System.out.print("降序为:");
for(int item:array){
System.out.print(item+" ");
}
}
}
3.冒泡排序的时间复杂度和空间复杂度
时间复杂度分析:
最好:O(n) 已经有序
最坏:O(n^2)
平均:O(n^2)
空间复杂度:O(1)
4.稳定性
稳定。由于我们是从前往后依次比较,只有大于或小于的情况才交换,因此具有相同大小的数据顺序不会发生变化。所以冒泡排序是稳定的。
5.冒泡排序的另一种写法---从后往前遍历
//升序 从后往前遍历,把较小的数放到前面。
private static void bubbleSort3(int[] array){
boolean isSortted=true;
for(int i=0;i<array.length-1;i++){
for(int j=array.length-1;j>i;j--){
if(array[j]<array[j-1]){
int temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
isSortted=false;
}
if(isSortted){
break;
}
}
}
}