冒泡排序和递归算法优化

冒泡排序算法

第一,冒泡排序是原地排序算法吗?数组

冒泡的过程只涉及相邻数据的交换操做,只须要常量级的临时空间,因此它的空间复杂度为 O(1),是一个原地排序算法。 函数

第二,冒泡排序是稳定的排序算法吗?优化

在冒泡排序中,只有交换才能够改变两个元素的先后顺序。为了保证冒泡排序算法的稳定spa

性,当有相邻的两个元素大小相等的时候,咱们不作交换,相同大小的数据在排序先后不会code

改变顺序,因此冒泡排序是稳定的排序算法。blog

第三,冒泡排序的时间复杂度是多少?排序

最好状况下,要排序的数据已是有序的了,咱们只须要进行一次冒泡操做,就能够结束 了,因此最好状况时间复杂度是 O(n)。而最坏的状况是,要排序的数据恰好是倒序递归

排列 的,咱们须要进行 n 次冒泡操做,因此最坏状况时间复杂度为 O(n2)。 get

冒泡排序优化(没有交换,提早退出)

// 冒泡排序,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; // 没有数据交换,提早退出  } }

 

递归

递归须要知足的三个条件:

1. 一个问题的解能够分解为几个子问题的解,何为子问题?子问题就是数据规模更小的问题。

2. 这个问题与分解以后的子问题,除了数据规模不一样,求解思路彻底同样

3. 存在递归终止条件:把问题分解为子问题,把子问题再分解为子子问题,一层一层分解下去,不能存在无限循环,这就须要有终止条件。

基本公式

f(n) = f(n-1)+f(n-2)

递归代码要警戒重复计算

除此以外,使用递归时还会出现重复计算的问题。例如 f(6) = f(5) + f(4) , f(7) = f(6) + f(5) , 能够看到计算f(6) 和 f(7) 的时候,明显的重复计算了f(5)。

public int f(int n) {
    if (n == 1) return 1;
    if (n == 2) return 2;
    // hasSolvedList 能够理解成一个 Map,key 是 n,value 是 f(n)
    if (hasSolvedList.containsKey(n)) {
        return hasSovledList.get(n);
    }
    int ret = f(n-1) + f(n-2);
    hasSovledList.put(n, ret);
    return ret;
}        

递归还有不少其余问题,例如在时间效率上,递归代码里多了不少函数调用,当这些函数调用的数量较大时,就会积聚成 一个可观的时间成本。

相关文章
相关标签/搜索