数据结构——算法、算法的时间复杂度和空间复杂度

来源:互联网 发布:软件部署结构图 编辑:程序博客网 时间:2024/06/05 04:55

什么是算法


·算法是解决特定问题求解,步骤的描述在计算机中表现为指令的有限序列,并且每条指令表示一个后多个操作。(就是你解决一道数学问题一步一步的求解的过程,在计算机中就是写程序时一条一条的指令)。
·算法设计的要求:正确性、可读性、健壮性、时间效率高和存储量低

时间复杂度

定义:在进行算法分析时,语句总的执行次数T(n)关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的复杂度就是算法的时间量度,记做:T(n)=O(f(n))。他表示随着问题规模n的增大,算法执行时间按的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度。其中f(n)是问题规模n的某个函数。
这样用大O()记述时间复杂度的方法被称为大O记法。
一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。(要注意是增长)

推导大O阶方法


1.用常数1取代运行时间中所有的加法常数。
2.在修改的运行函数中,只保留最高阶项。
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。

常数阶


先看下面这个代码

    int sum = 0,  n = 100;/*执行一次*/    sum = (n + 1) * 100 / 2;/*执行一次*/    printf("%d", sum);/*执行一次*/

整除算法的运行函数是f(n)=3,根据大O推导法将常数3改为1,没有最高次项,所以时间复杂度就为O(1)。
不管n是多少,这种运行次数是恒定的,执行时间也是恒定的算法,(不会随着n的增大,而发生变化)我们称之为具有O(1)的时间复杂度,又叫常数阶。

线性阶


线性阶的循环结构较为复杂,要想分析其时间复杂度,要搞清楚循环结构的循环情况。

    int i, sum = 0;    for(i = 1; i < n; i++)

这个循环结构要执行n次,所以他的时间复杂度为O(n)。

对数阶

    int count = 1;    while( count < n)    {        count = count * 2;    }

当count >= n时,也就是说有多少个2相乘后大于或等于n,就可以跳出循环,就是2^x=n,x = log2n,这个循环的时间复杂度为(logn)。(这里把2去掉是个啥意思?)

平方阶


下面的例子是循环嵌套,

    int i, j;    for(i = 0; i <n; i++)    {        for(j = 0; j < n; j++)        {        }    }

内循环要循环n次,外循环也要循环n次,所以这个循环的嵌套的次数一共是 n*n=n^2次,其时间复杂度为O(n^2)。
再看下面这个例子

    int i, j;    for(i = 0; i < m; i++)    {        for(j = 0; j < n; j++)        {        }    }

这个循环体的时间复杂度等于循环体的复杂度(m)乘以循环体的运行次数(n)就是O(m * n)。
再再看下面的例子

    int i, j;    for(i = 0; i < n; i++)    {        for(j = i; j < n; j++)        {        }    }

当i = 0时,内循环执行了n次,i=1时,内循环执行了n - 1次,以此类推,
n + (n - 1)+(n - 2) + ( n - 3 )+……1=1/2(n^2+n)(这是个等差数列,根据等差数列的求和公式可得出),按照大O推导法,只保留最高次项的n^2/2,去除最高次项相乘的常数就是0(n^2)。

阅读全文
0 0
原创粉丝点击