数据结构绪论

数据结构

通常意义上,我们将数据结构分为逻辑结构和存储结构。

逻辑结构
  • 集合结构
    集合结构中的数据元素除了同属于一个集合外无其他关系。
  • 线性结构
    线性结构中数据元素之间是一对一的关系。
  • 树结构
    树结构中的数据元素之间存在一种一对多的层次关系。
  • 图结构
    图结构的数据元素是多对多的关系

几种逻辑结构层次图:几种逻辑结构层次图
存储结构
即如何把数据元素存储到计算机的存储器中

  • 顺序存储结构(线型或其他)

是把数据元素存放在一组连续的地址空间中,其数据间的逻辑关系和存储关系相一致。

  • 链式存取结构(树、图结构)

是把数据元素存放在任意的存储单元里,可连续可不连续。用一个指针存放数据元素的地址,从而查找数据元素位置。

抽象数据类型(ADT)

是指一组性质相同的值得集合及定义在此集合上的一些操作的总称。
抽象:是指取出事物具有的普遍性的本质。它要求抽出问题的特征而忽略非本质的细节,是对具体事物的一个概括。
例如很多编程语言的整型,浮点型,字符型这些,指的就是数据类型。
在C语言中,按取值的不同,数据类型可以分为两类:

  • 原子类型:不可以再分解的基本类型,例如整型、浮点型、字符型等。
  • 结构类型:由若干个类型组合而成,是可以再分解的,例如整型数组是由若干整型数据组成的。

ADT的标准格式:

ADT 抽象数据名
Data
	数据元素之间逻辑关系的定义
Operation	
	操作
endADT

算法和算法分析

算法的特性

1)有穷性。即每一步必须在又穷时间内完成。
2)确定性。无二义性。
3)可行性。程序可通过基本操作运算执行有限次来实现。
4)输入。输入通常用形参表示,被调用时从主函数输入值。
5)输出。无输出的算法没有意义。

一个算法可以有零个或多个输入,也可以有一个或多个输出。

算法的时间复杂度

设计算法要尽量提高效率,这里的算法即是指算法的执行时间。
那么如何度量一个算法的执行时间呢?
这就引出了算法时间复杂度的概念

算法的时间复杂度取决于问题的规模待处理数据的状态

影响算法时间代价的最主要因素是问题规模。

问题规模一般用整数n表示,对于不同的问题n的含义不同。

  • 在排序运算中n为参加排序的记录数
  • 在矩阵运算中n为矩阵的阶数
  • 在多项式运算中n为多项式的项数
  • 在集合运算中n为集合中元素的个数
  • 在树的有关运算中n为树的结点个数
  • 在图的有关运算中n为图的定点数或边树。

显然,n越大算法的执行时间越长.
牢记以上n所代表的意义,对接下来计算时间复杂度有很大的帮助。

那么现在我们来看一个例子初步理解算法时间复杂度的运算

//第一种算法
int sum=0,n=100;//执行1次
for(int i=0;i<n;i++)//执行n+1次
{
sum+=i;//执行n次
}
//第二种算法
int sum=0,n=100;//执行1 次
sum=n*(n+1)/2;//执行1 次

综上我们得:
第一种算法执行了1+(n+1)+n=2n+2次
第二种算法执行了1+1=2次

如果我们把循环看做一个整体,忽略头尾判断的开销,俺么这两个算法就是n和1的差距

此时你可能还不太理解,为什么可以2n+2和2变成了n和1,不要着急,看下面的例子。

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

此时,算法包含两个for循环嵌套,外层执行100次,那么内层循环则执行1002次则该算法执行次数为1+n+n2+n2+n2=3n2+n+1。
由函数的渐进增长我们忽略头和尾那么得到该算法的时间复杂度为n2
同理对于三阶算法:T(n)=O(n3)
在这里我们展现了时间复杂度的表示方法。
算法的时间复杂度:
T(n)=O(f(n)),
其中f(n)是问题规模n的某个函数。
表示随问题规模n的增大,算法的执行时间增长率和f(n)的增长率相同。通俗讲就是(执行次数=时间)。

注意公式中T和O都为大写,O()成为大O记法。

计算时间复杂度攻略:
  • 用常数1代替运行次数中的加法常数。
  • 在修改后的运行次数函数中,只保留最高阶项。
  • 如果最高阶数不是1,则去除这个项相乘的常数。
    将算法分为
    1、常数阶 T(n)=O(1)
    2、线性阶:一般为非嵌套循环 T(n)=O(n)
    3、平方阶:嵌套(内外层循环)T(n)=O(n2)
    4、立方阶:三层嵌套 T(n)=O(n3)
    5、nlogn阶:O(nlogn)
    6、指数阶:O(2n)
    7、对数阶:看以下例子
int i=1;
while(i<=n)
{
i=i*3;
}

分析该程序可知,每次i*3之后,就距离n更近一步,设有x个3相乘后的结果大于n,则退出循环。
此时得到:
3x = n ——>x=log3n因此得到该算法的时间复杂度为O(log3n)。

常用的时间复杂度所耗费的时间从小到大依次是:

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

轻松做题务必牢记以上!!!

对于算法时间复杂度的度量分为最好时间复杂度,最坏时间复杂度以及平均时间复杂度
注:严蔚敏c语言版的数据结构中。只讨论最坏情况下的时间复杂度,即分析在最坏情况下,算法执行的上界。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值