数据结构之前,先来了解两个概念——时间复杂度
时间复杂度
由来:这里的时间复杂度不是程序运行的时间。评价一个算法的好坏,并不能通过程序运行的快慢来评估。因为程序的运行快慢还有很多因素,和计算机硬件有关,所以如果在不同的电脑上 ,运行的时间可能不一样 。那么这里的时间复杂度指啥,指的是算法中基本操作的执行次数。比如某一句基础语句执行了多少次。这样就可以很直观的评价一个算法的好坏了。
表示: 大O渐进表示法 O(N)
步骤: 首先用 F(N )来表示基础语句的执行次数,
例子:
//C语言
function(int N)
{
int temp = 0;
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
printf("%d ",temp++);
}
printf("\n");
}
for(int k = 0;k < N; ++k)
{
printf("%d ",temp++);
}
}
这里我们用 printf("%d ",temp++); 做基础语句,它一共执行了多少次呢?F(N) = N * N + 2 * N,所以O(F(N) ) = O(N^2);因为我们的大O渐进表示法只是保留执行次数的最高次幂。(官方语言看不懂)
下面写几个栗子。来进行充分的理解。总结大O渐进表示法如何表达。首先啊,大O 渐进表示法是算法的最坏情况,也就是说执行到最后一次操作,比如循环赵某个数,最坏情况就是循环的最后一次找到或者没有找到。
栗子1、
//C语言
void founc1(int N)
{
int L = 0;
int M = 10;
while (L < N)
{
++L;
}
while (M--)
{
++L;
}
}
解:这个程序呢,我们以L++为基础语句,那么我们可以看见 L++ 执行了 N + 10次,所以 F(N) = N + 10 ;那取最高次,大O渐进表示法就是 O (N)
栗子2、
//C语言
void founc2(int N , int M)
{
int i = 0;
while (i < N)
{
++i;
}
while (M--)
{
++i;
}
}
解:这个一看,就可以写下 F(N) = M + N。那么 O (F(N)) = O(M + N)。
栗子3、
//C语言
void founc3(int* arr, int row)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < row - i - 1; ++j)
{
if (arr[j] > arr[j +1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
解:这个是个简单草率的冒泡排序,是我写的简单草率昂。冒泡排序的规则,我们知道啊,第一次交换 row - 1次,第二次交换 row - 2 ……一直到最后一次,总的次数是多少呢?可以用等差求和的公式吧? 1+ 2 +3 +4 + 5 +(N-1),最后等于的就是(N(N+1))/2,F ( N ) = (N^2 + N)/2,所以是O (F(N) )= O(N^2)。
栗子4、
//C语言
void founc4(int* arr, int num)
{
int left = 0;
int right = sizeof(arr)/sizeof(int);
while (left < right)
{
int mid = (left + right) / 2;
if (arr[mid]==num)
{
return mid;
}
else if (mid < num)
{
left = mid + 1;
}
else
{
right = mid;
}
}
return -1;
}
解:这是个写法简单的二分查找的算法。这个时间复杂度是有点不好算的。我们先明白二分查找的算法。二分查找就像折纸。一直对着,二二分查找也是,一直从中间分知道找到这个数。那么最坏的情况就是一直找到最后的一个数。这个时候,一共分了几次呢?假设 N 个数。那么查找到最后,就是。1 * 2 *2 *2 *2……*2 = N,这个时候的次数 X ,是不是就是 2 ^X = N ;所以时间复杂度是 O (log N)。这里 log 是以2 为底。(是不是已经把对数忘了?^_^)
栗子5、
// C语言
int founc5(int num)
{
if (num < 3)
{
return num;
}
return founc5(num - 1) + founc5(num - 2);
}
解:这是个递归求斐波那契数列,给一个数,返回数列的第num个数。当知道什么是斐波那契数列的时候,就知道这个时间复杂度是多少了。当这个 num 太大的时候,可能计算机要算很久很久。可以想象成杨辉三角,直接说它的时间复杂度是 O ( 2^ N)。
时间复杂度就算到这儿了。这个是评判一个算法的好坏的经典手段。如何计算,在后面的数据结构阶段还会遇见很多程序。所以不着急。
其实还有个概念和它差不多,是空间复杂度。其实它是看一个程序临时占用多少内存空间。然而现在内存还是比较大的 8G ,16G。都还是比较大的,所以也不必考虑。但是如果一定要算,就算算变量的个数吧。也用大O渐进表示法。常数个变量就是O( 1 ),N个就是O(N)。和时间复杂度一样的。
数据结构开始了,一起走过。嘿~