数据结构 与 算法

一、基本概念和术语

1.1 数据、数据结构

数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。比如整型等数值类型、字符、声音、视频、图像等。

数据结构:是互相之间存在一种或多种特定关系的数据元素的集合。

1.2 算法

算法:是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,且每条指令表示一个或多个操作。

算法的特性:

  • 输入输出:算法有零个输入或多个输入,至少有一个或多个输出
  • 有穷性:执行有限的步骤后就会有结果,不会出现无限循环,每个步骤在可接受的时间内完成
  • 确定性:算法的每一步都具有确定的含义,不会出现二义性
  • 可行性:算法的每个步骤都是可行的,每一步都能得到正确的结果

算法的设计要求:

  • 正确性:指算法至少应该具有输入输出和加工处理无歧义性、能正确反映问题的需求,能得到问题的正确答案
  • 可读性:要便于阅读、理解和交流
  • 健壮性:输入数据不合法时,也能做出相关处理,不产生异常或其他错误
  • 时间/空间效率:时间效率高,存储空间低

二、时间复杂度(大O阶)

算法效率的度量有两种方式:一、事后统计:通过设计好的测试代码和数据,比较运行时间来确定算法效率的高低;二、事前估算:在写代码前,依据统计方法对算法进行估算。

第一种事后统计的方式有很多弊端,事后补救成本很高;所以一般会通过第二种事前估算的方式来统计算法的效率。

大O阶的时间复杂度就是事前分析统计。

2.1 时间复杂度

算法的时间复杂度,记作:T(n)= O(f(n))表示随着问题规模n的增加,算法执行时间增长率。一般随着n的增加,T(n)增长最慢的算法为最优算法。

一般使用大O阶来表示算法的时间复杂度,常见的算法复杂度如下:

2.2 大O阶的推导方法

1、用常数1取代所有加法常数

2、在修改后的运行次数函数中,只保留最高阶项

3、如果最高阶项存在且不是1,则去除与这个项相乘的常数得到的结果就是大O阶

2.2.1 常数阶

int sum = 0, n = 100;
sum = (n + 1) * n / 2;
System.out.println(sum);

这个算法的运行次数是f(n)= 3,依据上面的方法,用常数1取代所有加法常数3,然后没有高阶项,所以这个算法的时间复杂度就是常数阶O(1)。

2.2.2 线性阶

for (i = 0; i<n; i++) {
   // 时间复杂度为O(1)的程序步骤序列
}

循环体中需要执行n次,因此时间复杂度是O(n)。

2.2.3 对数阶

while (i < n) {
    i = i * 2;
    // 时间复杂度为O(1)的程序步骤序列
}

2^x=n,即x=\log_{2}n,也就是要执行\log n次,所以时间复杂度是O(\log n)。

2.2.4 平方阶

for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        // 时间复杂度为O(1)的程序步骤序列
    }
}

对于外部循环,是把内部时间复杂度为O(n)的代码,再执行 n 次。所以上面的时间复杂度是O(n^{2})。

2.3 最坏情况与平均情况

比如我们在n个随机数中查找某个数,最好的情况是我们查找的第一个数就是这个数,时间复杂度就是O(1),若最后一个才是要找的数,那时间复杂度就是O(n),这是最坏的情况。

一般没有特别说明的,都是指的最坏时间复杂度。

猜你喜欢

转载自blog.csdn.net/weixin_41231928/article/details/108447607