数据结构 第一章 绪论(下)

参考书籍:《严蔚敏版数据结构》学习视频:b站数据结构与算法基础(青岛大学-王卓)

目录

前言

二、怎样去描述算法

三、算法的特性

四、算法的时间和空间复杂度

1、算法的时间复杂度

2、例题(做题帮助我们理解时间复杂度T(n))

3、算法的空间复杂度

4、一些数据帮助我们更好的理解和记忆

总结


前言

“数据结构与算法”的研究内容除了逻辑结构(研究对象的特性及其相互之间的关系)和存储结构(有效地组织计算机存储)之外,还有有效地实现对象之间的“运算”关系--算法,算法就是用来解决问题的方法和步骤,接下来一起来简单了解算法和算法分析吧!


一、算法与程序

                程序 = 数据结构 + 算法

  •  数据结构通过算法实现操作
    • 算法根据数据结构设计程序

算法是解决问题的一种方法或一个过程,考虑如何将输入转换成输出,一个问题可以有多种算法。而程序是用某种程序设计语言对算法的具体实现。

二、怎样去描述算法

  • 自然语言:直接用中文或英文等自然语言去描述一个问题的处理方法;
  • 流程图:传统流程图、NS流程图(传统流程图比较繁琐,NS流程图比其简化);
  • 伪代码和类语言:类C语言(可以理解为处于C语言和伪代码之间);
  • 程序代码:C语言程序、JAVA语言程序设计。

三、算法的特性

一个算法必须满足的五个重要特性:(1)有穷性:一个算法必须总是在执行有穷步后结束,且每一步都必须在有穷时间内完成。(2)确定性:对于每种情况下所应执行的操作,在算法中都有确切的规定,不会产生二义性,使算法的执行者或阅读者都能明确其含义及如何执行。(3)可行性:算法中所有操作都可以通过已经实现的基本操作运算执行有限次来实现。(4)输入:一个算法有零个或多个输入。(5)输出:一个算法有一个或多个输出。

而一个算法的优劣可以从四个方面来评价:(1)正确性:在合理的数据输入下,能够在有限的运行时间内得到正确的结果。(2)可读性:为了人的阅读和交流,算法应易于人的理解。(3)健壮性:当输入的数据非法时,好的算法能适当地做出正确反应或进行相应处理,而不会产生一些莫名其妙的输出结果。(4)高效性:包括时间和空间两个方面。

算法的分析除了从正确性、可读性、健壮性评价外,主要考虑算法的执行效率。

四、算法的时间和空间复杂度

1、算法的时间复杂度

        衡量算法效率的方法主要有事后统计事前分析两种,由于事后统计的缺点很显然,一是要把算法转化成可执行的程序,二是时空开销的测算结果依赖于计算机的软硬件等环境因素,这很容易掩盖算法本身的优劣,所有我们通常采用事前分析,通过计算算法的渐进复杂度来衡量算法的效率。

算法运行时间 = 一个简单操作所需的时间 * 简单操作次数;

                      =\sum每条语句的执行次数(也称每条语句频度) * 该语句执行一次所需的时间;

假设执行每条语句所需的时间均为单位时间1,可得到:算法运行时间 = \sum每条语句频度

2、例题(做题帮助我们理解时间复杂度T(n))

       a、两个n X n矩阵相乘的算法可描述为:

for(i = 1; i <= n; i++)                    //频度为n+1
    for(j = 1; j <= n; j++){               //频度为n(n+1)
            c[i][j] = 0;                   //频度为n*n
            for(k = 0; k < n; k++)         //频度为n*n*(n+1)
                c[i][j] = c[i][j] + a[i][k] * b[k][j];  //频度为n*n*n
}

算法运行时间 = \sum每条语句频度  所以f(n) = 2n^3 + 3n^2 + 2n +1,

我们用算法的渐进时间复杂度(时间复杂度)O(f(n)) = T(n) ,

所以 T(n) = O(n^3)。

      b、再看一个简单的例题:T(n) = O(mn)

void exam(float x[][],int m,int n) {
	float sum[];
	for (int i = 0; i < m; i++) {  //频度为m
		sum[i] = 0.0;			
		for (int j = 0; j < n;j++)    //频度为m*n
			sum[i] += x[i][j];    
	}
	for (i = 0; i < m;i++) {		//频度为m
		printf("%lf",sum[i]);
	}
}

       c、一个难一丢丢的例题:立方阶 T(n) = O(n^3)

x = 1;
for (i = 1; i <= n; i++)
	for (j = 1; j <= i; j++)
		for(k = 1; k <= j;k++)
			x++;

 

       d、难(要好好思考)T(n) = O(lgn)

i = 1;
while (i <= n)
i = i * 2;

        设语句i = i * 2;执行次数为x次,由循环条件:i <= n 所以 2^x < n 得 x <= log2^n。即2^f(n) <= n 得 f(n) <= log2^n,取最大值f(n) = log2^n,T(n) = O(log2^n) = O(lgn)。

      e、有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同。例:顺序查找,在数组a[i]中查找等于e的元素,返回其所在位置。

for (i = 0; i < n; i++)
	if (a[i] == e) return i + 1; //找到,则返回是第几个元素
return 0;

最好情况:1次;

最坏情况:n次;

平均时间复杂度为:O(n)。

3、算法的空间复杂度

  • 空间复杂度:算法所需存储空间的度量,记作:S(n) = O(f(n))其中n为问题的规模(或大小)。
  • 算法要占据的空间:除了算法本身要占据的空间,输入/输出,指令,常数,变量等(具体存储量取决于问题的本身,与算法无关),算法要使用的辅助空间(需要分析)。
  • 通过一个例子来学习如何求解算法的空间复杂度:

            例:   数组逆序,将一维数组a中的n个数逆序存放到原数组中。

//算法一  S(n) = O(1)
for (i = 0; i < n / 2;i++) {
	t = a[i];
	a[i] = a[n - i - 1];
	a[n - i - 1] = t;
}  
/*仅需要另外借助一个变量t,与问题规模n大小无关,所以其空间复杂度为O(1)*/

//算法二    S(n) = O(n)
for (i = 0; i < n; i++)
	b[i] = a[n - i - 1];
for (i = 0; i < n; i++)
	a[i] = b[i];
/*需要另外借助一个大小为n的辅助数组b,所以其空间复杂度为O(n)*/

4、一些数据帮助我们更好的理解和记忆

 

 

 


总结

对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。所以自己看着办吧!!!(我可以申请摆烂么?吼吼吼)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值