系列文章目录
第一章:【数据结构】数据结构基础概念
文章目录
前言
数据结构是软件编程的基础,是程序员的基本功。
简介
数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及他们之间的关系和操作等相关问题的学科。
【程序设计 = 数据结构 + 算法】
名词解释
数据
是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。
符号必须具备的两个前提:
- 可以输入到计算机中
- 能被计算机程序处理
数据元素
是组成数据的,有一定意义的基本单位,在计算机中通常作为整体处理,也被称为记录。
数据项
一个数据元素可以由若干个数据项组成,数据项是数据不可分割的最小单位。
数据对象
是性质相同的数据元素的集合,是数据的子集。
数据结构
是相互之间存在一种或多种特定关系的数据元素的集合
类型 | 说明 |
---|---|
逻辑结构 | 指数据对象中数据元素之间的相互关系 |
集合结构 | 集合结构中的数据元素除了同属于一个集合外,他们之间没有其他关系 |
线性结构 | 线性结构中的数据元素之间是一对一的关系 |
树形结构 | 树形结构中的数据元素之间存在一对多的层次关系 |
图形结构 | 图形结构的数据元素是多对多的关系 |
物理结构 | 是指数据的逻辑结构在计算机中的存储形式 |
顺序存储结构 | 是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的 |
链式存储结构 | 是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的,需要一个指针存放数据元素的地址来反映其逻辑关系 |
数据类型
是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。
类型用来说明变量或表达式的取值范围和所能进行的操作。
按照取值的不同,分为两类:
- 原子类型:是不可以再分解的基本类型,包括整数。实型(就是小数),字符型等。
- 结构类型:由若干个类型组合而成,是可以再分解的,例如整型数组是由若干整型数据组成的。
抽象
指取出事物具有的普遍性的本质,"抽象"的意义在于数据类型的数学抽象特性。
抽象数据类型
指一个数学模型及定义在模型上的一组操作,体现了程序设计中问题分解、抽象和信息隐藏的特性。
(我们对已有的数据类型进行抽象,就有了抽象数据类型)
算法
是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
算法的五个特性:
- 输入、输出、有穷性、确定性、可行性
- 输入:算法具有零个或多个输入(可以是没有输入的,比如你打印个hello world的代码)
- 输出:算法至少有一个或多个输出
- 有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成
- 确定性:算法的每一步骤都具有明确的含义,不会出现二义性(在相同的条件下只有一条执行路径,相同的输入只有唯一的输出结果)
- 可行性:算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成
算法设计要求
-
正确性:
算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案
分为4个层次:
- 算法程序没有语法错误
- 算法程序对于合法的输入数据能够产生满足要求的输出结果
- 算法程序对于非法的输入数据能够得出满足规格说明的结果(大多时候的要求标准)
- 算法程序对于精心选择的,甚至刁难的测试数据都能有满足要求的输出结果
-
可读性
算法设计的另一目的是为了便于阅读、理解和交流
-
健壮性
输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果
-
时间效率高和存储量低
时间效率高是指算法的执行时间短,存储量指算法在执行过程中需要的最大存储空间,主要指内存和硬盘空间
- 算法效率的度量方法
-
事后统计方法
主要是通过设计好的测试仪程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,确定效率高低。
由于有以下缺点,该方法基本不予考虑
- 必须要花大量时间来编写测试程序
- 受计算机硬件和软件等环境因素影响太大,杂音太多,结果准确性不高
- 测试数据设计苦难, 和测试数据规模也有很大关系
-
事前分析估算方法
在计算机程序编制前,依据统计方法对算法进行估算。
程序运行时间决定因素有以下几点
- 算法采用的策略、方法
- 编译产生的代码质量
- 问题的输入规模
- 机器执行指令的速度
抛开与计算机软硬件的因素,一个程序的运行时间依赖于算法的好坏和问题的输入规模(输入量大小)。
最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。
-
渐进增长:
给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的 n > N,f(n)总是比g(n)大,那么我们说f(n)的增长渐进快于g(n)。
判断一个算法的好坏时,例如 3n+1,2n2,2n2+3n+1, n3+1:
- 可以忽略加法常数
- 与最高次项相乘的常数不重要
- 函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数
-
算法时间复杂度
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。
算法的时间复杂度,也就是算法的时间度量,记作:T(n) = O(f(n))。
他表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度,其中f(n)是问题规模n的某个函数。
-
推导大O阶(O(fn))
- 用常数1取代运行时间中的所有加法常数
- 在修改后的运行次数函数中,只保留最高阶项
- 如果最高阶项存在且不是1,则去除与整个项相乘的常数
得到的结果就是大O阶,分为常数阶O(1),线性阶O(n),对数阶O(logn),平方阶O(n2)等
-
最坏情况与平均情况
最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。
在应用中,这是一种最重要的需求。通常,除非特别指定,我们提到的运行时间都是最坏情况的运行时间。
平均运行时间时所有情况中最有意义的,因为它是期望的运行时间,但现实情况中。很难获取平均时间。
-
算法空间复杂度
现实中完全可以通过空间来换取时间,例如一个本来需要每次计算n次的结果,先把所有的情况都保存下来,然后根据输入去查找对应结果,就从O(n)变为了O(1)。
S(n) = O(f(n)),通常说的算法复杂度指时间复杂度
-
-
- 算法效率的度量方法
总结
本文简单介绍了学习数据结构的一些基础知识,下一章开始进入第一个具体的数据结构:线性表