我们评估一个程序的好坏,通常是以程序执行的速度以及程序所占用的内存为依据。自本篇开始,我们进入了数据结构的学习,本篇介绍时间复杂度及空间复杂度的计算
时间复杂度,指的是基本语句的执行次数。
例1
public void fun(int n){
int t = 1;
for(int i = 0; i < n; i++){
t++;
}
}
如上图,基本语句执行了n+1次
例2
void fun2(int n){
int y = 1;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
y++;
}
}
}
如上图,基本语句执行了n2+1次。
例3
public void fun(){
int t = 1;
for(int i = 0; i < 10; i++){
t++;
}
}
如上图,基本语句执行次数为11
例1 冒泡排序
static void mySort(int[] array){
for(int i = 0; i < array.length-1; i++){
boolean flg = true;
for(int j = 0; j < array.length - i -1; j++){
if(array[j] > array[j+1]){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flg = false;
}
}
if(flg == true){
break;
}
}
}
最坏的情况是,循环执行完毕时的操作次数。为n-1+n-2+n-3+·····0,是一个等差数列,最高项为n2.时间复杂度为O(n2)
例2 二分排序
static int searchValue(int[] array, int value){
int left = 0;
int right = array.length-1;
while(left <= right){
int mid = (left + right)/2;
if(array[mid] > value){
right = mid - 1;
}else if(array[mid] < value){
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
最坏的情况是,到最后,只剩下一个数才是value的时候,此时,n / 2x = 1,x = logn.时间复杂度为
O(logn)
例3 阶乘
int factorial(int n){
return n < 2 ? n : n * factorial(n-1);
}
函数总共执行了n次,时间复杂度为O(n)
例4 求斐波那契数列
int fabonacci(int n){
return n < 2 ? n : fabonacci(n-1)+fabonacci(n-2);
}
每次执行2n-1次函数,总共加起来是一个等比数列,最高项是2n,时间复杂度为O(2n).
空间复杂度,指的是程序所占内训的大小,以变量个数为依据。这里的变量不包括临时变量。
例1
static void mySort(int[] array){
for(int i = 0; i < array.length-1; i++){
boolean flg = true;
for(int j = 0; j < array.length - i -1; j++){
if(array[j] > array[j+1]){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flg = false;
}
}
if(flg == true){
break;
}
}
}
这里的形参是临时变量,变量flg每次都会循环刷新,所以,这个函数的空间复杂度为O(1)。
例2
void fun2(int m,int n){
int y = 1;
int[] array = new int[10];
for(int i = 0; i < m; i++){
array[i] = i;
for(int j = 0; j < n; j++){
y++;
}
}
}
里面有m+1个变量,所以空间复杂度为O(m).
例3
int fabonacci(int n){
return n < 2 ? n : fabonacci(n-1)+fabonacci(n-2);
}
递归每次调用函数,就会开辟一个空间,每return一次,就会有一个空间,总共开辟n个,空间复杂度为O(n).