一、时间复杂度
1.什么是时间复杂度
在计算机科学中,算法的时间复杂度本身是一个函数,它用于计算该算法的运行时间。但是,只有你将你的程序在你的设备中运行起来,才能知道它到底花费了多少时间,并且在每一个机器上的运行时间可能都不一样,所以很难确定其所花费的具体时间。但在一个算法中有很多语句,所以跑一个算法所需要的时间可以按照其中语句的执行次数来进行计算,所以一般算法中基本操作的执行次数,为算法的时间复杂度。
int calcu(int n)
{
int count = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
count++;
}
}
for(int h = 0; h < 3*n; h++)
{
count++;
}
int s = 20;
while(s--)
{
count++;
}
}
calcu 函数的基本执行次数为:
n^2 + 3n + 20
实际上当 n开始变得很大的时候,其余两项加起来的值对第一项的影响很小,所以通常疏略不记,俗称取极限值,所以在计算时间复杂度时,其实并不一定要对计算的次数进行准确计算,而只需要求大概的执行次数,所以我们一般使用大O的渐进表示法。
2.大O渐进分析法
渐进分析法最常用的表示方法是用于描述函数渐近行为的数学符号。
大O渐进分析法的几种特点:
在运行函数的时候,只保留执行次数最高的项。
如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O⑴。
大O渐进分析法一般给予的是这个函数的上界,但不是上确界,它表示的是算法计算所表现的一个最坏的执行结果,这就保证了算法的运行时间一般小于这个时长。
如果最高阶存在且不为1,则去除与这个项目相乘的常数,其所得到的结果就是大O阶。
在使用大O的渐进分析法后,calcu的时间复杂度为:
O(n*n)
在实际情况下一般关注算法的最坏运行情况,所以算法时间复杂度为O(N)。
二、空间复杂度
空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。
空间复杂度不是计算该函数占用了多大的内存空间,而是计算算法中变量的个数,因为空间复杂度的计算规则与时间复杂度类似,所以也使用大O分析法。
注:因为函数运行时所需要的空间已经在编译期间为其分配好了具体的空间,因此空间复杂度主要通过函数在运行时其中的变量所申请的额外空间来进行确定。
三、二叉树的基本理解
节点的度:一个节点含有的子树的个数称为该节点的度;
叶节点或终端节点:度为0的节点称为叶节点;
非终端节点或分支节点:度不为0的节点;
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点,是亲兄弟
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
树的高度或深度:树中节点的最大层次;
堂兄弟节点:双亲在同一层的节点互为堂兄弟;
节点的祖先:从根到该节点所经分支上的所有节点;
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>0)棵互不相交的树的集合称为森林;
1.3树的表示
树中常用的是孩子兄弟表示法。
typedef int DataType;
struct Node
{
struct Node* Child; // 第一个孩子结点
struct Node* Brother; // 指向其下一个兄弟结点
DataType data; // 结点中的数据域
};