数据结构--基本结构和算法复杂度讲解

1、数据结构的基本概念

是一门研究非数值运算(即无法用数学公式和方程来描述,而是用表,树,图之类的数据)的程序设计中的计算机操作对象以及它们之间的关系(线性和非线性)和操作的学科。
数值型的数据:整数,实数
非数值型的数据:文字,图像,图形,声音等。
数据元素之间不是孤立存在的,它们之间存在着某种关系,数据元素相互之间的关系称为结构。

2、数据结构的两个层次

逻辑结构:描述数据元素之间的逻辑关系,与数据存储无关
存储结构(物理结构):数据元素及其关系在计算机存储器中的结构(存储方式)
二者综合起来建立了数据元素之间的结构关系。
逻辑结构:
(1)分为线性结构和非线性结构;线性结构分为线性表,栈和队列,串,数组和广义表,非线性结构分为树和图
(2)分为集合结构:数据元素之间同属于一个集合
线性结构:数据元素之间是一对一的关系
树形结构:数据元素之间是一对多的关系
图形结构:数据元素之间是多对多的关系
存储结构:
顺序存储结构:用连续的存储单元依次存储数据元素,逻辑关系由元素的存储位置表示。
链式存储结构:任意的存储单元存储数据元素,逻辑关系用指针表示。
索引式存储结构:在存储结点信息的同时,建立附加的索引表(关键字,地址)
散列式存储结构:根据结点的关键字直接计算该结点的存储地址
在这里插入图片描述

知道了数据的结构,那么如何有效地实现对象之间的‘运算’关系?
引出算法–解决问题的方法和步骤
算法运行时间 = E( 每条语句的执行次数 x 该语句执行一次所需的时间)求和

例1:

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
	}

***注释:对于第一行:执行次数为n次,因为还要判断条件不成立时,退出循环,所以要多执行一次即n+1次。
对于第二行,因为不满足第一行的条件的话,不会执行,相对于第一行,它属于内层循环,只用执行n次,而自己还要判断条件不成立时,退出循环,所以也是n+1次。
算法的时间消耗T(n) = 2n ^ 3 + 3n^ 2 +2n +1

简单方法:只比较数量级,数量级越大计算时间越长
若有某个辅助函数f(n),使得当n趋于无穷大时,T(n)/f(n)的极限值为不等于0的常数,则称f(n)是T(n)的同数量级函数,记作O(f(n)),简称时间复杂度这个定义有点类似于极限思想,如T(n) = 10n^ 2 —-—>O(n^ 2)
因此例1为O(n^ 3)

分析算法时间复杂度的方法:
1、找出语句频度最大的那条语句作为基本语句
2、计算基本语句的频度得到问题规模n的某个函数f(n)
3、取其数量级用符号“O”表示

例子2:

x=0;y=0
for(int k=0;k<n;k++)//n+1
	x++//n
for(int i=0;i<n;i++)//n+1
	for(int j=0;j<n;j++)//n*(n+1)
	y++;				//n*n

因此为O(n*n)

例子3:

float sum[];
for(int i=0;i<m;i++){
	sum[i]=0;
	for(int j=0;j<n;j++)
		sum[i] +=x[i][j];//m*n
}
for(i=0;i<m;i++)
	cout<<i<< ":" <<sum[i] <<end;
}

因此O(m*n)

总结:时间复杂度是由嵌套最深层语句的频度决定的

注意:还可以使用级数的方法,如例子1中
在这里插入图片描述
对于例子2:
在这里插入图片描述
具体怎么算参考级数求和或者泰勒公式可得。

例子4:

i=1;		//a
while(i<=m)
	i=i*2	//b

分析:若循环执行1次:i=12=2
若循环执行2次:i=2
2=2^ 2
若循环执行n次:i = 2 ^n
又因为i<=m,所以2 ^ n<=m,所以n= log2^ m(取了最大值)
例子5:
有的情况下,算法中基本操作重复执行的次数随问题的输入数据集不同而不同

顺序查找,在数组a[i]中查找值等于e的元素,返回其所在位置
for(i=0;i<n;i++)
	if(a[i]==e)return i+1;//找到,则返回第几个元素
return 0;

分析:如果e=a[0],则只需要查找一次
如果e=a[1],则只需要查找两次
如果e=a[i],则需要查找n次
所以,O(n)
因此可以把算法时间复杂度分为三种
最坏时间复杂度,平均时间复杂度,最好时间复杂度
对于复杂的算法,可以将它分成几个容易估算的部分,然后利用大O加法法则和乘法法则,计算算法的时间复杂度:
a)加法法则:
在这里插入图片描述
复杂度从低到高的顺序依次为:
常数阶,对数阶,线性阶,线性对数阶,平方阶,立方阶,k次方阶,指数阶

空间复杂度:算法所需存储空间的度量,记作S(n) = O(f(n)),其中n为问题的规模(或大小)
算法要占据的空间
算法本身要占据的空间:输入/输出,指令,常数,变量等
算法要使用的辅助空间
例子5:
将一维数组中的n个数逆序存放到原数组中

for(i=0;i<n/2;i++){
	t=a[i];
	a[i] = a[n-i-1]
	a[n-i-1] =t;

S(n)=O(1),其中t为辅助空间,只需要一个变量空间

for(i==0,i<n;i++)
	b[i]=a[n-i-1];
for(i=0;i<n;i++);
	a[i]=b[i]

S(n)=O(n),其中b[i]由a决定,a需要多大的空间,b就需要多大。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值