数据结构和算法_绪论、算法、时间复杂度和空间复杂度

绪论

什么是数据结构
数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。
程序设计=数据结构+算法
数据结构就是关系,就是数据元素相互之间存在的一种或多种特定关系的集合。

传统上,我们把数据结构分为逻辑结构和物理结构。
逻辑结构:是指数据对象中数据元素之间的相互关系,也是我们今后需要关注和讨论的对象。
物理结构:是指数据的逻辑结构在计算机中的存储形式。

四大逻辑结构:集合结构、线性结构、树形结构、图形结构。

  • 集合结构:集合结构中的数据元素除了同属于一个集合外,它们之间没有其他不三不四的关系。
    在这里插入图片描述
  • 线性结构:线性结构中的数据元素之间是一对一的关系。
    在这里插入图片描述
  • 树形结构:树形结构中的数据元素之间存在一种一对多的层次关系。
    在这里插入图片描述
  • 图形结构:图形结构的数据元素是多对多的关系。
    在这里插入图片描述

物理结构:根据物理结构的定义,我们实际上研究的就是如何把数据元素存储到计算机的存储器中。
存储器主要是针对内存而言的,像硬盘、软盘、光盘等外部存储器的数据组织通常用文件结构来描述。
数据元素的存储结构形式有两种:顺序存储和链式存储。

  • 顺序存储结构:是把数据元素放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。
    例如编程语言中的数组结构。
    在这里插入图片描述
    现在在银行、医院等地方,都设置了排队系统。也就是每个人去了,先领一个号,等着叫号,交到你的时候就可以存一百块或看病。而在等待的时候爱干嘛干嘛,只要及时回来就行。这些情况下,你关注的是前一个号有没有被叫到,叫到了,下一个就该轮到你了。
    链式存储结构就是这样的道理,相比起顺序存储结构就灵活多了。
  • 链式存储结构:是把数据元素放在任意的存储单元里,这组存储单元可以是连续的,也可以式不连续的。
    很显然,这样说的话链式存储结构的数据元素存储关系并不能反映其逻辑关系,因此需要用一个指针存放数据元素的地址,这样子通过地址就可以找到相关联数据元素的位置。
    在这里插入图片描述

算法

什么是算法
算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
算法的五个基本特征:输入、输出、有穷性、确定性和可行性。

  • 输入
    算法具有零个或多个输入。
    尽管对于绝大多数算法来说,输入参数都是必要的。但是有些时候,像打印“Hello World!”,就不需要参数。
void print()
{
	printf("Hello World!\n");
}
  • 输出
    算法至少有一个或多个输出。
    算法一定要有输出,输出的形式可以是打印形式输出,也可以式返回一个值或多个值等。
  • 有穷性
    指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
  • 确定性
    算法的每一个步骤都具有确定的含义,不会出现二义性。
    算法在一定条件下,只有一条执行路径,相同的输入只能由唯一的输出结果。
    算法的每个步骤都应该被精确定义而无歧义。
  • 可行性
    算法的每一个步骤都必须是可行的,也就是说,每一步都能够通过执行有限次数完成。
  • 正确性
    算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案。
    大体分为四个层次:
    算法程序没有语法错误。
    算法程序对于合法输入能够产生满足要求的输出。
    算法程序对于非法输入能够产生满足规格的说明。
    算法程序对于故意刁难的测试输入都有满足要求的输出结果。
  • 可读性
    算法设计的目的是为了便于阅读、理解和交流。方便计算机执行,便于他人阅读和自己日后阅读修改。
  • 健壮性
    当输入数据不合法时,算法也能做出相关处理,而不是产生异常、崩溃或莫名其妙的结果。
  • 时间效率高和存储量低
    当输入数据不合法时,算法也能做出相关处理,而不是产生异常、崩溃或莫名其妙的结果。

时间复杂度和空间复杂度

算法效率的度量方法
设计算法要尽量的提高效率,这里效率高一般指的是算法的执行时间。
事前分析估算方法:在计算机程序编写前,依据统计方法对算法进行估算。
一个高级语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:

  • 算法采用的策略,方案
  • 编译产生的代码质量
  • 问题的输入规模
  • 机器执行指令的速度
    由此可见 ,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间依赖于算法的好坏和问题的输入规模。(所谓的问题输入规模是指输入量的多少)
    算法效率的度量方法

函数的渐近增长
给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说f(n)的增长渐近快于g(n)。
末尾的常数项不重要,可以忽略。
与最高次项相乘的常数不重要,可以忽略。
最高次项的指数大的,函数随着n的增长,结果也会变得增长特别快。

判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高项)的阶数。

算法时间复杂度的定义
在进行算法分析时,语句总的执行次数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,则去除与这个项相乘的常数。
得到的最后结果就是打O阶。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
最坏情况与平均情况
查找一个有n个随机数组中的某个数字,最好的情况是第一个数字就是,那么算法的时间复杂度为O(1),但也有可能这个数字就在最后一个位置,那么时间复杂度为O(n)。
平均运行时间是期望的运行时间。
最坏运行时间是一种保证。在应用中,这是一种最重要的需求,通常除非特别指定,提到的运行时间都是最坏情况的运行时间。

算法的空间复杂度
在写代码时,可以用空间来换取时间。
算法的空间复杂度通过计算算法所需的存储空间实现,算法的空间复杂度的计算公式记作:S(n)=O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。
通常,我们都是用“时间复杂度”来指运行时间的需求,是用“空间复杂度”指空间需求。
当直接要求我们求“复杂度”时,通常指的是时间复杂度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值