-
数据结构
-
数据结构基本知识
-
数据
-
定义
-
所有能输入到计算机中的描述客观事物的符号
-
-
分类
-
数值型数据
-
整数、实数等
-
-
非数值型数据
-
文字、图像、图形、声音等
-
-
-
-
数据元素/节点/记录
-
数据基本单位
-
在计算机程序中通常作为一个整体进行考虑和处理
-
-
数据项/域
-
有独立含义的数据最小单位
-
若干数据项组成一个数据元素
-
-
数据对象
-
相同特性的数据元素的集合,数据的一个子集
-
-
数据结构
-
相互之间存在一种或多种特定关系的数据元素的集合
-
”结构“指数据元素之间存在的关系
-
研究 将带有关系的数据存储在计算机中,并进行相关操作
-
分类
-
逻辑结构
-
数据元素之间关系
-
与数据的存储无关,独立于计算机,从具体问题中抽象出来的数学模型
-
分类
-
集合
-
同属于一个集合(数据结构仅此一种集合关系)
-
-
线性结构
-
特点
-
一条线,不会分叉
-
有唯一的开始和唯一的结束
-
除了最后一个元素外,每个元素都有唯一的直接后继(后面那个)
-
-
分类
-
线性表
-
栈
-
队列
-
数组
-
广义表
-
-
-
非线性结构
-
树形结构
-
特点
-
一个对多个,多个分支
-
树枝之间不可相交
-
-
-
图形结构
-
特点
-
多个对多个,任何一个节点都可能和其他节点有关系
-
-
-
-
-
-
存储结构/数据的物理结构(数据元素及其关系在计算机内存中的表示——映像)
-
数据元素及其关系在计算机中的存储方式
-
分类
-
顺序存储
-
逻辑上相邻的元素在计算机内的存储位置也是相邻的
-
顺序存储采用一段连续的存储空间,将逻辑上相邻的元素存储在连续的空间内,中间不允许有空
-
顺序存储可以快速定位第几个元素的地址,但插入和删除时需要移动大量元素
-
-
链式存储
-
逻辑上相邻的元素在计算机内的存储位置不一定是相邻的
-
每个节点除了数据域,还有一个指针域,记录下一个元素的存储地址
-
-
散列存储/哈希存储
-
由节点的关键码值决定节点的存储地址
-
用散列函数确定数据元素的存储位置于关键码之间的对应关系
-
散列存储通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度
-
多种处理冲突的方法
-
-
索引存储
-
除建立存储节点信息外,还建立附加的索引表来标识节点的地址
-
索引表由若干索引项组成
-
若每个节点在索引表中都有一个索引项,则该索引表称为稠密索引
-
若一组节点在索引表中只对应于一个索引项,则该索引表称为稀疏索引
-
-
索引项的一般形式是关键字、地址
-
-
-
-
-
运算
-
对数据元素可以施加的操作及这些操作在相应的存储结构上的实现
-
-
-
-
抽象数据类型
-
数据类型
-
一些基本数据结构可用数据类型来实现
-
规定了程序执行期间变量和表达的所有可能的取值范围,以及在这些数值范围上所允许进行的操作
-
数据类型=值的集合+值集合上的一组操作
-
-
而另一些常用的数据结构,如栈、队列、树、图等,不能直接用数据类型来表示
-
将数据对象、数据对象之间的关系和数据对象的基本操作封装在一起的一种表达方式 一个数学模型以及定义在此数学模型上的一组操作
-
形式定义
-
抽象数据类型可用(D,S,P)三元组表示
-
D 数据对象
-
S D上的关系集
-
P 对D的基本操作集
-
-
-
-
-
抽象数据类型的实现
-
用已有的数据类型定义描述存储结构
-
用函数定义描述他的操作
-
-
-
-
操作运算数据结构——算法
-
定义
-
对特定问题求解方法或步骤的一种描述,是指令的有限序列。每个指令表示一个或多个操作
-
-
描述
-
自然语言
-
流程图:传统流程图,NS流程图
-
伪代码,类语言:类c语言
-
程序代码
-
-
算法与程序
-
算法是方法
-
程序是算法的具体实现
-
-
特性
-
有穷性
-
有穷步内结束
-
有穷时间内完成
-
-
确定性
-
可行性
-
0个或多个输入
-
一个或多个输出
-
-
算法设计要求
-
正确
-
语法错误无
-
几组输入数据得到满足要求结果
-
对于精心选择、典型、苛刻带有刁难性的几组输入数据能得到满足要求的结果
-
对于一切合法输入数据能得到满足要求结果
-
-
可读性
-
给人看
-
-
健壮性
-
输入非法数据时,算法恰当做出反应进行相应处理,而不是产生莫名其妙的输出结果
-
处理出错的方法,不应时中断程序的执行,而应是返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理
-
-
高效性
-
少时间、低存储
-
-
-
算法效率
-
时间效率:算法所耗费时间
-
度量
-
事后统计
-
事前分析
-
大致等于计算机执行一种简单的操作所需的时间与算法中进行的简单操作次数乘积(每条语句执行次数(语句频度)x该语句执行一次所需时间)假设执行每条语句所需的时间均为单位时间,对算法的运行时间的讨论即可转化为讨论发算法中所有语句的执行次数,即频度之和了
-
仅比较算法的数量级 T(n)为时间消耗,f(n)为辅助函数,当n趋近于无穷大时,Tn比fn的极限值为不等于零的常数,则称fn是Tn同数量级的函数,记作Tn=O(fn),称O(fn)为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度
-
例. Tn=2n^3+3n^2+2n+1,n趋近于无穷大,limTn/n^3=2,则n趋近于无穷大时,Tn与n^3是同阶或同数量级,引入大O,则Tn记作,Tn=O(n^3) 则只需要找能得n^3的语句找出来
-
不必计算所有操作的执行次数,只考虑算法中基本操作执行的次数,他是问题规模n的某个函数,用Tn表示
-
算法时间复杂度定义: 算法中基本语句重复执行的次数是问题规模n的某个函数fn,算法的时间量度记作:Tn=O(fn)
-
找算法运行时间贡献最大的语句 看执行次数最多的
-
n越大算法执行时间越长 不同数据类型n表示不同: 排序:n为记录数 矩阵:n为矩阵阶数 多项式:n为多项式项数 集合:n为元素个数 树:n为树的结点个数 图:n为图的顶点数或边数
-
-
算法时间复杂度分析基本方法: 找出语句频度最大的那条语句作为基本语句 计算基本语句的频度得到问题规模n的某个函数fn 取其数量级用符号O表示
-
嵌套最深层语句的频度决定时间复杂度
-
级数算法
-
对数级
-
-
-
注意:有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同
-
-
最坏时间复杂度
-
平均时间复杂度:所有可能输入实例在等概率出现的情况下,算法的期望运行时间
-
最好时间复杂度
-
-
-
对于复杂的算法,可以将它分成几个容易估算的部分,然后利用大O加法法则和乘法法则计算
-
加法
-
乘法
-
-
算法时间效率的比较
-
当n取得很大时 O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
-
-
-
-
-
-
-
-
-
空间效率:算法执行过程中所耗费的存储空间
-
记作:Sn=O(fn)
-
算法要占据的空间
-
输入输出数据所占空间
-
必需
-
-
算法本身所占空间
-
可通过精简算法来缩减,但这个压缩量很小,可以忽略不计
-
-
算法要使用的辅助空间
-
-
空间效率与算法辅助空间有关
-
将辅助空间变为与n有关的函数
-
-
-
-
将一个算法从指数阶降到多项式阶,再降到对数阶,这是一件多么振奋人心的事!!
-
斐波那契
-
-
-
Tn>=Fn,是一个指数阶的算法
-
-
-
记录前两项的值,只需一次加法就可得到当前项
-
-
时间复杂度为多项式阶
-
-
-
中间结果只是为了下一次使用,根本不需要记录,可以采用迭代法进行算法设计
-
-
时间复杂度变为O(1)
-
-
-
O(logn)自己查
-
-
-
-
线性表
-
定义
-
具有相同特性的数据元素的一个有限序列
-
元素具有相同特性
-
数据元素可以是简单类型或复杂类型
-
数据元素间的关系是线性关系
-
有限个
-
-
-
名称
-
-
ai 只是一个抽象的符号,其具体含义在不同的情况下可以不同
-
-
-
类型定义(抽象数据类型)
-
-
InitList(&L)初始化:构造一个空的线性表L
-
DestroyList(&L)销毁线性表L:删除 初始条件:线性表L已存在
-
ClearList(&L)清除线性表L:将线性表L重置为空表(表本身还在) 初始条件:线性表L已存在
-
ListEmpty(L)判断一个表是否为空:空表,返回true;否则返回false 初始条件:线性表L已存在
-
ListLength(L)求一个线性表的长度:返回线性表中的数据元素个数 初始条件:。。。
-
GetElem(L,i,&e)获取元素:用e返回线性表L中第i个数据元素的值 初始条件:线性表L已存在,1<=i<=ListLength(L)
-
LocateElem(L,e,compare())定位,查找:返回L中第一个与e满足compare()的数据元素的位序。这样的数据元素不存在则返回值为0 初始条件:线性表L已存在,compare()是数据元素判定函数
-
PriorElem(L,cur_e,&pre_e)查找前驱:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败;pre_e无意义 初始条件:线性表L存在
-
NextElem(L,cur_e,&next_e)查找后继:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败;next_e无意义 初始条件:线性表L存在
-
ListInsert(&L,i,e)插入元素:在L的第i个位置之前插入新的数据元素e,L的长度加一 初始条件:线性表L已存在,1<=i<=ListLength(L)+1
-
LIstDelete(&L,i,&e)删除元素:删除L的第i个数据元素,并用e返回其值,L的长度减一 初始条件:线性表L已存在,1<=i<=ListLength(L)
-
ListTraverse(&L,visited())遍历:依次对线性表中每个元素调用visited() 初始条件:线性表L已存在
-
-
-
存储结构
-
顺序
-
定义概念
-
逻辑上相邻元素,物理存储上仍相邻 逻辑位序与物理位序差一
-
知道某个元素的存储位置就可以计算其他元素的存储位置:随机存取
-
第i+n个数据元素的存储位置=第i个数据元素的存储位置+线性表每个元素占的存储单元个数*n
-
所有数据元素的位置都可由第一个数据元素的存储位置得到:找某元素数量级为O(1)
-
loc(ai)=loc(a1)+(i-1)*每个元素占存储单元个数
-
-
-
依次存储,地址连续
-
-
术语
-
基地址
-
线性表的第一个数据元素的存储位置
-
-
-
实现
-
一维数组
-
用一变量表示顺序表的长度属性
-
-
优点
-
存储密度大(节点本身所占存储量/结点结构所占存储量)
-
可随机存取表中任意元素
-
-
缺点
-
插入删除某一元素时,需移动大量元素
-
浪费存储空间
-
属于静态存储形式,数据元素的个数不能自由扩充(溢出的时候)
-
-
-
链式表
-
定义概念
-
用一组物理位置任意的存储单元来存放线性表的数据元素
-
逻辑次序和物理次序不一定相同
-
存储该元素的同时也存储下一个元素的地址
-
每个结点包含两个域:数据域,指针域
-
最后一个指针域为空
-
-
有一个记录第一个元素地址的头指针
-
单链表是由头指针唯一确定的,因此单链表可以用头指针的名字来命名
-
-
-
术语
-
结点:数据元素的存储映像。由数据域和指针域两部分组成
-
链表:n个结点由指针链组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构
-
单链表、双链表、循环链表
-
单链表或线性链表:结点只有一个指针域的链表
-
双链表:结点有两个指针域的链表 前驱的地址+数据元素+后继的地址
-
循环链表:首尾相接的链表
-
-
头指针、头节点、首元结点
-
头结点可有可无
-
有无头结点
-
如何表示空表
-
无:头指针为空
-
有:头结点的指针域为空
-
-
头结点好处
-
便于首元结点的处理: 首元结点的地址保存在头结点的指针域中,与链表其他位置一致,无需进行特殊处理
-
便于空表和非空表的统一处理: 无论链表是否为空,头指针都是指向头结点的非空指针,所以空表与非空表的处理也就统一了
-
-
头结点数据域
-
可空,也可存放线性表长度等附加信息,但此节点不能计入链表长度值
-
-
-
-
-
-
特点
-
访问只能通过头指针进入链表,并通过每个结点的指针域依次向后顺序扫描其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等(顺序存取法)<——>顺序表(随机存取法)
-
-
实现
-
单链表带头结点
-
结构体:一个任意类型,一个指针型
-
-
-
-
-
-
数据结构+算法基本知识
![](https://img-home.csdnimg.cn/images/20240711042549.png)