【数据结构与算法】第一章 复杂度

1.什么是算法

算法是用于解决特定问题的一系列的执行步骤。

两数相加:

public static int plus(int a, int b){
	return a + b;
}

求n个数的和:

public static int sum(int n){
	int result = 0;
	for(int i = 1; i <= n; i++0){
		result += i;
	}
	return result;
}

使用不同的算法,解决同一个问题,效率可能相差非常大。

  • 比如:求第 n 个斐波那契数(fibonacci number)
//方式一:递归,当n比较大时要耗费很多时间
public static int fib1(int n) {
		if (n <= 1)
			return n;
		return fib1(n - 1) + fib1(n - 2);
	}

//方式二:推荐
public static int fib2(int n) {
	if (n <= 1)
		return n;

	int first = 0;
	int second = 1;

	for (int i = 0; i < n - 1; i++) {
		int sum = first + second;
		first = second;
		second = sum;
	}
	return second;
}

2.如何评判一个算法的好坏

如果单从执行效率上进行评估,可能会想到这么一种方案:

  • 比较不同算法对同一组输入的执行处理时间。
  • 这种方案也叫事后统计法

上述方案有明显的的缺点:

  • 执行时间严重依赖硬件以及运行时各种不确定的环境因素。
  • 必须编写相应的测算代码。
  • 测试数据的选择比较难保证公正性。

一般情况下从以下维度来评估算法的优劣:

  • 正确性、可读性、健壮性(对不合理输入的反应能力和处理能力)。
  • 时间复杂度(time complexity):估算程序指令的执行次数(执行时间)。
  • 空间复杂度(space complexity):估算所需占用的存储空间。

测试代码运行所使用时间的小工具:

package wuyp.java;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Times {
	private static final SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss.SSS");
	
	public interface Task {
		void execute();
	}
	
	public static void test(String title, Task task) {
		if (task == null) return;
		title = (title == null) ? "" : ("【" + title + "】");
		System.out.println(title);
		System.out.println("开始:" + fmt.format(new Date()));
		long begin = System.currentTimeMillis();
		task.execute();
		long end = System.currentTimeMillis();
		System.out.println("结束:" + fmt.format(new Date()));
		double delta = (end - begin) / 1000.0;
		System.out.println("耗时:" + delta + "秒");
		System.out.println("-------------------------------------");
	}
}

3.大O表示法(Big O)

一般用大O表示法来描述复杂度,它表示的是数据规模n对应的复杂度。

忽略常数、系数、低阶

  • 9 >> O(1)
  • 2n + 3 >> O(n)
  • n2 + 2n + 6 >> O(n2)
  • 4n3 + 3n2 + 22n + 100 >> O(n3)
  • log2n 、log9n >> O(logn)
  • 写法上,n3 等价于 n^3

注意:大O表示法仅仅是一种粗略的分析模型,是一种估算,能帮助我们短时间内了解一个算法的执行效率。

4.常见的复杂度

在这里插入图片描述
复杂度排序:

  • O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

5.fib函数的时间复杂度分析

在这里插入图片描述

注意:有时候算法之间的差距,往往比硬件方面的差距还要大

6.算法的优化方向

  • 用尽量少的存储空间
  • 用尽量少的执行步骤(执行时间)
  • 根据情况可以 时间换空间 或 空间换时间

7.多个数据规模的情况

时间复杂度:O(n + k)

public static void test(int n, int k){
	for(int i = 0; i < n; i++){
		System.out.println("test");
	}
	for (int i = 0; i < k; i++){
		System.out.println("test");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值