数据结构.docx
《数据结构.docx》由会员分享,可在线阅读,更多相关《数据结构.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构
第一章
数据(data)—所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素(dataelement)—数据的基本单位,也称节点(node)或记录(record)
数据项(dataitem)—有独立含义的数据最小单位,也称域(field)
数据结构(datastructure)—数据元素和数据元素关系的集合
根据数据元素间关系的基本特性,有四种基本数据结构
★(集合)——数据元素间除“同属于一个集合”外,无其它关系
★线性结构——一个对一个,如线性表、栈、队列
★树形结构——一个对多个
★图状结构——多个对多个
数据的逻辑结构—只抽象反映数据元素的逻辑关系
数据的存储(物理)结构—数据结构在计算机中的表示
存储结构分为:
顺序存储结构——借助元素在存储器中的相对位置来表示数据元素间的逻辑关系
链式存储结构——借助指示元素存储地址的指针表示数据元素间的逻辑关系
数据类型—高级语言中指数据的取值范围及其上可进行的操作的总称
抽象数据类型按其值的不同特性,分为三种类型:
•原子类型:
变量的值是不可分解的。
•固定聚合类型:
变量的值由确定数目的成分按某种结构组成。
•可变聚合类型:
其值的成分数目不确定。
算法(algorithm)—解决某一特定问题的具体步骤的描述,是指令的有限序列
算法特性—
算法的评价—衡量算法优劣的标准
v正确性(correctness)
v可读性(readability)
v健壮性(robustness)
v效率与低存储量
第二章
线性结构特点:
在数据元素的非空有限集中
★存在唯一的一个被称作“第一个”的数据元素
★存在唯一的一个被称作“最后一个”的数据元素
★除第一个外,集合中的每个数据元素均只有一个前驱
★除最后一个外,集合中的每个数据元素均只有一个后继
线性表:
一个线性表是n个数据元素的有限序列
顺序表:
用一组地址连续的存储单元存放一个线性表叫顺序表。
实现逻辑上相邻—物理地址相邻和随机存取。
顺序存储结构的优缺点
v优点
●逻辑相邻,物理相邻
●可随机存取任一元素
●存储空间使用紧凑
v缺点
●插入、删除操作需要移动大量的元素
●预先分配空间需按最大空间分配,利用不充分
●表容量难以扩充
线性表的链式存储结构特点:
v用一组任意的存储单元存储线性表的数据元素
v利用指针实现了用不相邻的存储单元存放逻辑上相邻的元素
v每个数据元素ai,除存储本身信息外,还需存储其直接后继的信息
v结点
●数据域:
元素本身信息
●指针域:
指示直接后继的存储位置
线性链表:
结点中只含一个指针域的链表叫线性链表,也叫单链表。
单链表特点
●它是一种动态结构,整个存储空间为多个链表共用
●不需预先分配空间
●指针占用额外存储空间
●不能随机存取,查找速度慢
循环链表(circularlinkedlist)
v循环链表是表中最后一个结点的指针指向头结点,使链表构成环状
v特点:
从表中任一结点出发均可找到表中其他结点,提高查找效率
v操作与单链表基本一致,循环条件不同
●单链表p或p->link=NULL
●循环链表p或p->link=H
双向链表(doublelinkedlist)
单链表具有单向性的缺点,在查找某节点的直接前趋的时间复杂度将达到O(n)。
第三章
栈的定义和特点
v定义:
限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,
表头—栈底,不含元素的空表称空栈
v特点:
先进后出(FILO)或后进先出(LIFO)
队列的定义及特点
v定义:
队列是限定只能在表的一端进行插入,在表的另一端进行删除的线性表
§队尾(rear)——允许插入的一端
§队头(front)——允许删除的一端
v队列特点:
先进先出(FIFO)
存在问题
当front=0,rear=M-1时,再有元素入队发生溢出——真溢出
当front0,rear=M-1时,再有元素入队发生溢出——假溢出
第四章
串(string)是字符串的简称,是由零个或多个字符组成的有限序列。
要求组成线性表的所有数据元素都是字符。
串的存储结构定长顺序存储表示:
事先定义字符串的最大长度,字符串存储在一个定长的存储区中。
堆分配:
在程序执行过程中,利用标准函数malloc和free动态地分配或释放存储字符串的存储单元。
优点:
可以根据具体情况,灵活地申请适当数目的存储空间,从而提高存储资源的利用率。
第五章
树(tree)是n(n>=0)个结点的有限集T,其中:
●有且仅有一个特定的结点,称为树的根(root)
●当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,……Tm,其中每一个集合本身又是一棵树,称为根的子树(subtree)
特点:
树中各子树是互不相交的集合
基本术语
v结点(node)——表示树中的元素,包括数据项及若干指向其子树的分支
v结点的度(degree)——结点拥有的子树数
v叶子(leaf)——度为0的结点
v孩子(child)——结点子树的根称为该结点的孩子
v双亲(parents)——孩子结点的上层结点叫该结点的~
v兄弟(sibling)——同一双亲的孩子
v树的度——一棵树中最大的结点度数
v结点的层次(level)——从根结点算起,根为第一层,它的孩子为第二层……
v深度(depth)——树中结点的最大层次数
v森林(forest)——m(m0)棵互不相交的树的集合
二叉树是n(n0)个结点的有限集,它或为空树(n=0),或由一个根结点和两棵分别称为左子树和右子树的互不相交的二叉树构成
特点
★每个结点至多有二棵子树(即不存在度大于2的结点)
★二叉树的子树有左、右之分,且其次序不能任意颠倒
完全二叉树是指这样的二叉树:
除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。
最下一层上的结点都集中在该层最左边的若干位置上
满二叉树一定是完全二叉树,反之完全二叉树不一定是满二叉树。
二叉树的顺序存储结构
●实现:
按满二叉树的结点层次编号,依次存放二叉树中的数据元素
●特点:
◆结点间关系蕴含在其存储位置中
◆浪费空间,适于存完全二叉树和一般二叉树
遍历二叉树和线索二叉树
v遍历——如何按某条搜索路径访问二叉树中的每个顶点,使每个节点被访问一次且仅被访问一次
v方法
●先序遍历:
先访问根结点,然后分别先序遍历左子树、右子树
●中序遍历:
先中序遍历左子树,然后访问根结点,最后中序遍历右子树
●后序遍历:
先后序遍历左、右子树,然后访问根结点
●按层次遍历:
从上到下、从左到右访问各结点
线索二叉树
定义:
前驱与后继:
在二叉树的先序、中序或后序遍历序列中两个相邻的结点互称为~
线索:
指向前驱或后继结点的指针称为~
线索二叉树:
加上线索的二叉链表表示的二叉树叫~
线索化:
对二叉树按某种遍历次序使其变为线索二叉树的过程叫~
实现:
在有n个结点的二叉链表中必定有n+1个空链域
在线索二叉树的结点中增加两个标志域
lt:
若lt=0,lc域指向左孩子;若lt=1,lc域指向其前驱
rt:
若rt=0,rc域指向右孩子;若rt=1,rc域指向其后继
树的存储结构
v双亲表示法
●实现:
定义结构数组存放树的结点,每个结点含两个域:
◆数据域:
存放结点本身信息
◆双亲域:
指示本结点的双亲结点在数组中位置
●特点:
找双亲容易,找孩子难
哈夫曼树(Huffman)——带权路径长度最短的树
定义
●路径:
从树中一个结点到另一个结点之间的分支构成这两个结点间的~
●路径长度:
路径上的分支数
●树的路径长度:
从树根到每一个结点的路径长度之和
●树的带权路径长度:
树中所有带权结点的路径长度之和
第六章
图的定义和术语
图(Graph)——图G是由两个集合V(G)和E(G)组成的,记为G=(V,E)
其中:
V(G)是顶点的非空有限集,E(G)是边的有限集合,边是顶点的无序对或有序对
有向图——有向图G是由两个集合V(G)和E(G)组成的
其中:
V(G)是顶点的非空有限集,E(G)是有向边(也称弧)的有限集合,弧是顶点的有序对,记为,v,w是顶点,v为弧尾,w为弧头。
无向图——无向图G是由两个集合V(G)和E(G)组成的
其中:
V(G)是顶点的非空有限集,E(G)是边的有限集合,边是顶点的无序对,记为(v,w)或(w,v),并且(v,w)=(w,v)
有向完备图——n个顶点的有向图最大边数是n(n-1)
无向完备图——n个顶点的无向图最大边数是n(n-1)/2
权——与图的边或弧相关的数叫~
网——带权的图叫~
子图——如果图G(V,E)和图G‘(V’,E‘),满足:
●V’V
●E’E
则称G‘为G的子图
顶点的度
●无向图中,顶点的度为与每个顶点相连的边数
●有向图中,顶点的度分成入度与出度
◆入度:
以该顶点为头的弧的数目
◆出度:
以该顶点为尾的弧的数目
路径——路径是顶点的序列V={Vi0,Vi1,……Vin},满足(Vij-1,Vij)E或E,(1路径长度——沿路径边的数目或沿路径各边权值之和
回路——第一个顶点和最后一个顶点相同的路径叫~
简单路径——序列中顶点不重复出现的路径叫~
简单回路——除了第一个顶点和最后一个顶点外,其余顶点不重复出现的回路叫~
连通——从顶点V到顶点W有一条路径,则说V和W是连通的
连通图——图中任意两个顶点都是连通的叫~
连通分量——非连通图的每一个连通部分叫~
强连通图——有向图中,如果对每一对Vi,VjV,ViVj,从Vi到Vj和从Vj到Vi都存在路径,则称G是~
邻接顶点如果(u,v)是E(G)中的一条边,则称u与v互为邻接顶点。
邻接矩阵——表示顶点间相联关系的矩阵
定义:
设G=(V,E)是有n1个顶点的图,G的邻接矩阵A是具有以下性质的n阶方阵
特点:
无向图的邻接矩阵对称,可压缩存储;有n个顶点的无向图需存储空间为n(n+1)/2
有向图邻接矩阵不一定对称;有n个顶点的有向图需存储空间为n²
无向图中顶点Vi的度TD(Vi)是邻接矩阵A中第i行元素之和或第i列的元素之和
有向图中顶点Vi的度TD(Vi)为行和列元素之和
◆顶点Vi的出度是A中第i行元素之和
◆顶点Vi的入度是A中第i列元素之和
邻接表:
实现:
为图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(有向图中指以Vi为尾的弧)
特点:
无向图中顶点Vi的度为第i个单链表中的结点数
有向图中
◆顶点Vi的出度为第i个单链表中的结点个数
◆顶点Vi的入度为整个单链表中邻接点域值是i的结点个数
逆邻接表:
有向图中对每个结点建立以Vi为头的弧的单链表
深度优先遍历(DFS)
v方法:
从图的某一顶点V0出发,访问此顶点;然后依次从V0的未被访问的邻接点出发,深度优先遍历图,直至图中所有和V0相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止
广度优先遍历(BFS)
v方法:
从图的某一顶点V0出发,访问此顶点后,依次访问V0的各个未曾访问过的邻接点;然后分别从这些邻接点出发,广度优先遍历图,直至图中所有已被访问的顶点的邻接点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止
生成树
定义:
所有顶点均由边连接在一起,但不存在回路的图叫~
深度优先生成树与广度优先生成树
生成森林:
非连通图每个连通分量的生成树一起组成非连通图的
说明一个图可以有许多棵不同的生成树
●所有生成树具有以下共同特点:
◆生成树的顶点个数与图的顶点个数相同
◆生成树是图的极小连通子图
◆一个有n个顶点的连通图的生成树有n-1条边
◆生成树中任意两个顶点间的路径是唯一的
◆在生成树中再加一条边必然形成回路
●含n个顶点n-1条边的图不一定是生成树
最小生成树
构造最小生成树方法
方法一:
普里姆(Prim)算法
◆算法思想:
设N=(V,{E})是连通网,TE是N上最小生成树中边的集合
◆初始令U={u0},(u0V),TE=
◆在所有uU,vV-U的边(u,v)E中,找一条代价最小的边(u0,v0)
◆将(u0,v0)并入集合TE,同时v0并入U
◆重复上述操作直至U=V为止,则T=(V,{TE})为N的最小生成树
◆算法实现:
图用邻接矩阵表示
◆算法描述
◆算法评价:
T(n)=O(n²)
方法二:
克鲁斯卡尔(Kruskal)算法
◆算法思想:
设连通网N=(V,{E}),令最小生成树
◆初始状态为只有n个顶点而无边的非连通图T=(V,{}),每个顶点自成一个连通分量
◆在E中选取代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边,选取下一条代价最小的边
◆依此类推,直至T中所有顶点都在同一连通分量上为止
拓扑排序:
AOV网——用顶点表示活动,用弧表示活动间优先关系的有向图称为顶点表示活动的网(ActivityOnVertexnetwork),简称AOV网
●若是图中有向边,则vi是vj的直接前驱;vj是vi的直接后继
●AOV网中不允许有回路,这意味着某项活动以自己为先决条件
拓扑排序——把AOV网络中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程叫~
●检测AOV网中是否存在环方法:
对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有序序列中,则该AOV网必定不存在环
拓扑排序的方法
v在有向图中选一个没有前驱的顶点且输出之
v从图中删除该顶点和所有以它为尾的弧
v重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止
关键路径
AOE网(ActivityOnEdge)——也叫边表示活动的网。
AOE网是一个带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间
路径长度——路径上各活动持续时间之和
关键路径——路径长度最长的路径叫~
Ve(j)——表示事件Vj的最早发生时间
Vl(j)——表示事件Vj的最迟发生时间
e(i)——表示活动ai的最早开始时间
l(i)——表示活动ai的最迟开始时间
l(i)-e(i)——表示完成活动ai的时间余量
关键活动——关键路径上的活动叫~,即l(i)=e(i)的活动
求关键路径步骤
v求Ve(i)
v求Vl(j)
v求e(i)
v求l(i)
v计算l(i)-e(i)
求最短路径步骤
初使时令S={V0},T={其余顶点},T中顶点对应的距离值
若存在,为弧上的权值
若不存在,为
从T中选取一个其距离值为最小的顶点W,加入S
对T中顶点的距离值进行修改:
若加进W作中间顶点,从V0到Vi的距离值比不加W的路径要短,则修改此距离值
重复上述步骤,直到S中包含所有顶点,即S=V为止
第七章
查找——也叫检索,是根据给定的某个值,在表中确定一个关键字等于给定值的记录或数据元素
关键字——是数据元素中某个数据项的值,它可以标识一个数据元素
查找方法评价
v查找速度
v占用存储空间多少
v算法本身复杂程度
v平均查找长度ASL(AverageSearchLength):
为确定记录在表中的位置,需和给定值进行比较的关键字的个数的期望值叫查找算法的~
静态查找表
仅作查询和检索操作的查找表。
动态查找表
在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已存在的某个数据元素,此类表为动态查找表。
顺序查找
查找过程:
从表的一端开始逐个进行记录的关键字和给定值的比较
折半查找
查找过程:
每次将待查记录所在区间缩小一半
适用条件:
采用顺序存储结构的有序表
分块查找
查找过程:
将表分成几块,块内无序,块间有序;先确定待查记录所在块,再在块内查找
适用条件:
分块有序表
算法实现
v用数组存放待查记录,每个数据元素至少含有关键字域
v建立索引表,每个索引表结点含有最大关键字域和指向本块第一个结点的指针
动态查找表的特点:
表结构本身是在查找过程中动态生成的,即对于给定值key,若表中存在其关键字等于key的纪录,则返回查找成功,否则插入关键字等于key的纪录。
二叉排序树
定义:
二叉排序树或是一棵空树,或是具有下列性质的二叉树:
●若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
●若它的右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值
●它的左、右子树也分别为二叉排序树
二叉排序树的插入
●插入原则:
若二叉排序树为空,则插入结点应为新的根结点;否则,继续在其左、右子树上查找,直至某个叶子结点的左子树或右子树为空为止,则插入结点应为该叶子结点的左孩子或右孩子
●二叉排序树生成:
从空树出发,经过一系列的查找、插入操作之后,可生成一棵二叉排序树
哈希查找
基本思想:
在记录的存储地址和它的关键字之间建立一个确定的对应关系;这样,不经过比较,一次存取就能得到所查元素的查找方法
定义
哈希函数——在记录的关键字与记录的存储地址之间建立的一种对应关系叫~
●哈希函数是一种映象,是从关键字空间到存储地址空间的一种映象
●哈希函数可写成:
addr(ai)=H(ki)
★ai是表中的一个元素
★addr(ai)是ai的存储地址
★ki是ai的关键字
哈希表——应用哈希函数,由记录的关键字确定记录在表中的地址,并将记录放入此地址,这样构成的表叫~
哈希查找——又叫散列查找,利用哈希函数进行查找的过程叫~
处理冲突的方法
开放定址法
方法:
当冲突发生时,形成一个探查序列;沿此序列逐个地址探查,直到找到一个空位置(开放的地址),将发生冲突的记录放到该地址中,即Hi=(H(key)+di)MODm,i=1,2,……k(km-1)
其中:
H(key)——哈希函数
m——哈希表表长
di——增量序列
分类
◆线性探测再散列:
di=1,2,3,……m-1
◆二次探测再散列:
di=1²,-1²,2²,-2²,3²,……±k²(km/2)
◆伪随机探测再散列:
di=伪随机数序列
再哈希法
方法:
构造若干个哈希函数,当发生冲突时,计算下一个哈希地址,即:
Hi=Rhi(key)i=1,2,……k其中:
Rhi——不同的哈希函数
特点:
计算时间增加
链地址法
方法:
将所有关键字为同义词的记录存储在一个单链表中,并用一维数组存放头指针
第八章
排序定义——将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列叫~
排序分类
v按待排序记录所在位置
●内部排序:
待排序记录存放在内存
●外部排序:
排序过程中需对外存进行访问的排序
排序基本操作
v比较两个关键字大小
v将记录从一个位置移动到另一个位置
直接插入排序
v排序过程:
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序
折半插入排序
v排序过程:
用折半查找方法确定插入位置的排序叫~
希尔排序(缩小增量法)
v排序过程:
先取一个正整数d1希尔排序特点
子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列
希尔排序可提高排序速度,因为
分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)总体上看是减小了
关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序
增量序列取法
无除1以外的公因子
最后一个增量值必须为1
冒泡排序
排序过程
●将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上
●对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置
●重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止
快速排序
基本思想:
通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序
排序过程:
对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key
●初始时令i=s,j=t
●首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换
●再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换
●重复上述两步,直至i==j为止
●再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止
简单选择排序
排序过程
●首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换
●再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换
●重复上述操作,共进行n-1趟排序后,排序结束
堆排序
堆的定义:
n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆
堆排序:
将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列,这个过程叫~
堆排序需解决的两个问题:
●如何由一个无序序列建成一个堆?
●如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?
第二个问题解决方法——筛选
●方法:
输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换;重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”
归并排序
归并——将两个或两个以上的有序表组合成一个新的有序表,叫~
2-路归并排序
排序过程
●设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1
●两两合并,得到n/2个长度为2或1的有序子序列
●再两两合并,……如此重复,直至得到一个长度为n的有序序列为止