排序(上):为什么插入排序比冒泡排序更受欢迎?

排序(上):为什么插入排序比冒泡排序更受欢迎?

最经典、常用排序:冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序

时间复杂度为O( n 2 n^2 n2) : 冒泡、插入、选择

O(nlogn) : 快排、归并

O(n) : 桶、计数、基数

插入排序和冒泡排序的时间复杂度都相同,为什么更倾向于插入排序而不是冒泡?

如何分析一个“排序算法”

(1).排序算法的执行效率

1.最好、最坏、平均情况时间复杂度

2.时间复杂度的系数、常数、低阶

3.比较次数和交换移动次数

基于比较的排序算法的执行过程会涉及两个操作,一种是元素比较大小,另一种是元素交换或移动

(2)排序算法的内存消耗

针对算法的空间复杂度,引入一个概念“原地排序”,特指空间复杂度是O(1)的排序算法

(3)排序算法的稳定性

如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变

比如我们有2,9,3,4,8,3,按照大小排序之后就是2,3,3,4,8,9,数据中有两个3,经过某排序算法排序之后,如果两个3的前后顺序没有发生变化,这种排序算法叫做稳定的排序算法

比如给电商交易系统中的“订单”排序,订单有两个属性,一个是下单时间,一个是订单金额,现在有10W条数据,我们希望按照金额从小到大对订单数据排序,对于金额相同的订单,按照时间从早到晚有序,做法:先按照下单时间给订单排序,排序完成之后,用稳定的排序算法,按照订单金额重新排序,两遍排序之后,得到的订单数据就是按照金额从小到大排序,金额相同的订单按照下单时间从早到晚排序

稳定排序算法可以保持金额相同的两个对象,在排序之后的前后顺便不变。第一次排序之后,所有订单按照下单时间从早到晚有序,第二次排序,相同金额的订单仍然保持下单时间从早到晚有序

冒泡排序

冒泡排序只会操作相邻的两个数据,每次操作都会对相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足就让它两互换,一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,完成n个数据的排序工作

对4,5,6,3,2,1从小到大进行排序,得经过6次冒泡

当某次冒泡操作已经没有数据交换时说明已经达到完全有序,不用再继续执行后续的冒泡操作

//冒泡排序,a表示数组,n表示数组大小
public void bubbleSort(int[] a ,int n){
  if(n <= 1 )return ; 
  for(int i =0 ;i < n ;++i){
    //提前退出冒泡循环的标志位
    boolean flag = false;
    for(int j = 0 ; j < n - i - 1 ; ++j){
      if(a[j] > a[j+1]){  //交换
        int tmp = a[j];
        a[j] = a[j+1];
        a[j+1] = tmp;
        flag = true;//表示有数据交换
      }
    }
    if(!flag) break;//没有数据交换,提前退出
  }
}

冒泡的过程只涉及相邻数据的交换操作,

你可能感兴趣的:(数据结构与算法)