什么是数据结构
数据结构是计算机存储、组织数据的方式,大致划分为:
线性结构
数组、链表、栈、队列、哈希表
树形结构
AVL树、红黑树、B树、堆、Trie、哈夫曼树、并查集
图形结构
邻接矩阵、邻接表
什么是算法
基本概念
算法是用于解决特定问题的一系列的执行步骤。解决同一个问题,可能有多种算法,应该选用最易读的,并且执行效率最高的代码。
以下代码示例都是算法:
计算两个数的和:
public int plus(int a, int b){
return a + b;
}
复制代码计算 1 到 n 的和:
public int sum(int n){
int sum = 0;
for (int i = 0; i <= n; i++) {
sum += i;
}
return sum;
}
复制代码
不同算法的优劣
经典的斐波拉契数列问题:
0 1 1 2 3 5 8 13 21 ... 第一个数 + 第二个数 = 第三个数
求第 n 个数是多少?
复制代码
以下有两种解题思路,分别是使用递归和循环:
思路一:递归
static public int fib1(int n){
if (n <= 1) { return n; }
return fib1(n - 1) + fib1(n - 2);
}
复制代码
思路二:循环
static public int fib2(int n){
if (n <= 1) { return n; }
int first = 0;
int second = 1;
int temp = 0;
for (int i = 0; i < n - 1; i++) {
temp = first + second;
first = second;
second = temp;
}
return temp;
}
复制代码
如果把参数 n 的数值设置大一点,可以明显感觉到使用循环要比递归快很多。
2.如何评判一个算法的好坏
事后统计法:比较两个算法的执行时间。
一般从以下维度评判一个算法的优劣:
正确性
可读性
健壮性
时间复杂度:估算程序指令的执行次数、执行时间
空间复杂度:估算程序运行所占用的空间
大 O 表示法
一般用大 O 表示法来描述复杂度,它表示的是数据规模 n 对应的复杂度。大 O 表示法仅仅是一种粗略的分析模型,是一种估算,能在短时间了解一个算法执行效率。
忽略常数、系数、低阶
9 > O(1)
2n + 3 > O(n)
n² + 2n + 6 > O(n²)
4n3 + 3n2 + 22n + 100 > O(n^3)
log2n、log9n 统称为 logn (忽略底数)
复杂度从小到大:O(1) < O(logn) < O(n) < O(nlogn) < O(n²) < O(n^3) < O(2^n) < O(n!) < O(n^n)
再来回顾之前的斐波拉契数列,分析两个算法的时间复杂度:
所以当传入的参数 n 非常大时,两种算法所表现出来的差距也非常大。由此可见一个高效率算法的重要性。