汇编数据结构与算法大全Word文档下载推荐.docx
《汇编数据结构与算法大全Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《汇编数据结构与算法大全Word文档下载推荐.docx(33页珍藏版)》请在冰豆网上搜索。
算法中的所有待实现的运算必须在原则上能够由人使用笔和纸在做有穷
次运算后完成。
(4)输入:
一个算法具有0个或多个输入的外界量,它们是算法开始前对算法最初给
出的量。
(5)输出:
一个算法至少产生一个输出,它们是与输入有某种关系的量。
对一个算法的描述可以采用自然语言、数学语言、约定的符号语言、以及图解等方式。
算法的分析
求解同一个问题可以有多种不同的算法,评价一个算法的优劣除了正确性和简明性外,
主要考虑两点:
一是执行算法所耗费的时间,二是执行算法所耗费的存储空间,特别是辅
助存储空间的耗费。
就这两者而言,前者显得比后者更为重要,在数据结构中往往更注重
对算法执行时间的分析。
一个算法所耗费的时间是该算法中每条语句的执行时间之和,而
每条语句的执行时间是该语句执行次数(频度)与该语句一次执行所需时间的乘积。
2.1.3线性表
线性表是n≥0个元素的一个有限序列:
(al,a2,a3,....an-1,an)
线性表的一个重要特性是可以按照诸元素在表中的位置确定它们在表中的先后次序。
若n≥0,则a1为第一个元素,an为最后一个元素。
元素ai-l先于ai,我们称ai-l为ai的前驱;
ai在ai-1之后,ai为ai-1的后继。
除第一个元素外,每个元素都有一个且仅有一个直接前驱;
除最后一个元素外,每个元素都有一个且仅有一个直接后继。
用顺序存储结构存储的线性表称做顺序表;
用链式存储结构存储的线性表称做链表;
用散列方法存储的线性表称做散列表。
如果对线性表插入和删除运算发生的位置加以限制,
则成为两种特殊的线性表——栈和队列。
若线性表中的元素都是单个字符,则称做串。
$算法与程序的区别
算法的含义与程序十分相似,但二者又有区别。
一个程序不一定满足有穷性,操作系统就是如此,只要整个系统不被破坏、操作系统就永远不会停止,所以操作系统程序不是一个算法。
另外,程序中的指令必须是机器可以执行的,而算法中的指令则无此限制。
但是,一个算法如果用机器可执行的语言书写,则它就是一个程序。
2.1.4线性表的存储
有多种存储方式能将线性表存储在计算机内,其中最常用的是顺序存储和链接存储。
线性表的顺序存储
线性表的顺序存储是最简单的存储方式。
程序通常用一个足够大的数组,从数组的第
一个元素开始,将线性表的结点依次存储在数组中。
即线性表的第i个结点存储在数组的
第i(0≤i≤n-1)个元素中,用数组元素的顺序存储来体现线性表中结点的先后次序关系。
用数组存储线性表的最大优点是能直接访问线性表中的任一结点。
用数组存储线性表的缺点主要有两个:
一是程序中的数组通常大小是固定的,可能会
与线性表的结点可以任意增加和减少的要求相矛盾;
二是执行线性表的结点插入、删除操
作时要移动存于数组中的其他元素,使插入和删除操作不够简便。
线性表的链接存储
线性表链接存储是用链表存储线性表,最简单的用单链表。
如从链表的第一个表元开
始,将线性表的结点依次存储在链表的各表元中。
即线性表的第i个结点存储在链表的第
i(0<i<n-1)个表元中。
链表的每个表元除要存储线性结点的信息外,还要有一个成分用
来存储其后继结点的指针。
单链表就是通过链接指针来体现线性表中结点的先后次序关系。
每个链表还要有一个指向链表的第一个表元,链表的最末一个表元的后继指针值为空。
用
链表存储线性表的优点是线性表的每个表元的后继指针就能完成插入或删除的操作,不需
移动任何表元。
其缺点也主要有两条:
一是每个表元增加了一个后继指针成分,要花费更多的存储空
间;
二是不便随机地直接访问线性表的任一结点。
2.1.5线性表的运算
查找运算
查找线性表的第i(0≤i≤n-l)个表元;
在线性表中查找具有给定键值的表元;
插入运算
把新表元插在线性表的第i(0≤i≤n)个位置上;
把新表元插在具有给定键值的表元的前面或后面;
删除运算
删除线性表的第i(0≤i≤n-1)个表元;
删除线性表中具有给定键值的表元;
其他运算
统计线性表元的个数;
输出线性表各表元的值;
复制线性表;
线性表分析;
线性表合并;
线性表排序;
按某种规则整理线性表。
2.1.6数组
数组是有限个同类型数据元素组成的序列。
一个二维数组(或称矩阵)可以看成是由
m个行向量所组成的向量,也可以看成是由n个列向量所组成的向量。
数组的运算主要有
查找或存取数组中某个元素。
由于计算机存储单元是一维的结构,而数组是多维的结构,因此就必须把多维结构映
射为一维的结构,即把多维结构按一定次序排列成一维的,常用的排列次序有行优先顺序
和列优先顺序两种。
给出任一数组元素的下标,可以直接计算数组元素的存放地址。
二维数组元素地址的
计算公式是:
(l)行优先顺序下:
LOC(aij)=LOC(a11)+((i-1)×
n+(j-l))×
λ
(2)列优先顺序下:
LOC(aij)=LOC(a11)+((j-1)×
m+(i-l))×
式中,n和m分别为数组每行和每列的元素个数,λ为每个数组元素占用的存储单元
个数。
2.1.7稀疏矩阵
具有大量0元素的矩阵称做稀疏矩阵。
对于稀疏矩阵可以进行压缩存储,只存储非0
元素。
若非0元素的分布有规律,则可以用顺序方法存储非0元素,仍可以用公式计算数
组元素的地址。
一般的稀疏矩阵主要有两种存储方法。
三元组法和十字链表法。
2.1.8广义表
广义表(又称列表)是线性表的推广,是由零个或多个单元素或子表所组成的有限序
列。
广义表和线性表的区别在于:
线性表的成分都是结构上不可分的单元素,而广义表的
成分既可以是单元素,又可以是有结构的表。
广义表一般记做:
LS=(d1,d2,.,dn)
其中LS是广义表的名字,n是长度,d是广义表成分。
广义表有如下特征:
(1)广义表的元素可以是子表,而子表的元素还可以是子表。
(2)广义表可被其他广义表所共享(引用)。
(3)广义表可以是递归的表,即广义表也可以是本身的一个子表。
和线性表类似,可对广义表进行的运算有查找、插入和删除等。
但广义表的两个非常
重要的基本运算是取广义表表头HEAD(LS)和取广义表表尾TAIL(LS)。
2.1.9树
树的基本概念
树是n(n>0)个结点的有穷集合,有且仅有一个称为根的结点;
其余结点分为m(m≥0)个互不相交的非空集合,T1,T2,.,Tm,这些集合中的每一个都是一棵树,称为
根的子树。
在树上,根结点没有直接前趋。
对树上任一结点X来说,X是它的任一子树的根结点
唯一的直接前趋。
树上任一结点所拥有的子树的数目称为该结点的度。
度为0的结点称为
叶子或终端结点。
度大于0的结点称为非终端结点或分支点。
一棵树中所有结点的度的最
大值称为该树的度。
若树中结点A是结点B的直接前趋,则称A为B的双亲或父结点,
称B为A的孩子(即“子女”)或子结点。
任何结点A的孩子B也就是A的一棵子树的根
结点,父结点相同的结点互称为兄弟。
一棵树上的任何结点(不包括根本身)称为根的子
孙。
反之若B是A的子孙,则称A是B的祖先,结点的层数(或深度)从根开始算起:
根的层数为1,其余结点的层数为其双亲的层数加1。
一棵树中所有结点层数的最大值称为
该树的高度或深度。
树的基本运算
(1)求根ROOT(T),引用型运算,其返回值是结点X在树T的根结点。
(2)求双亲PARENT(T,X),引用型运算,其结果是结点X在树T上的;
若X是树T
的根或X不在T上,则返回值为一特殊标志。
(2)求孩子CHILD(T,X,i),引用型运算,其结果是树T上的结点X的第i个孩子;
若X不在T上或X没有第i个孩子,则返回值为一特殊标志。
(3)建树CREATE(X,T1,.,Tk)k≥1,加工型运算,其作用是建立一棵以X为根,
以T1,.,Tk为第1,.k棵子树的树。
(4)剪枝DELETE(T,X,i),加工型运算,其作用是删除树T上结点X的第i棵子树;
若T无第i棵子树,则为空操作。
2.1.10二叉树
二叉树的基本概念
二叉树是n≥0个结点的有穷集合,它或者是空集,或者同时满足下述两个条件:
有且仅有一个称为根的结点;
其余结点分为两个互不相交的集合T1、T2,T1与T2都
是二叉树,并且T1与T2有顺序关系(T1在T2之前),它们分别称为根的左子树和右子树。
二叉树是一类与树不同的树形结构。
它们的区别是:
第一,二叉树可以是空集,这种
二叉树称为空二叉树。
第二,二叉树的任一结点都有两棵子树(当然,它们中的任何一个
可以是空子树),并且这两棵子树之间有次序关系,也就是说,它们的位置不能交换。
相应
地,二叉树上任一结点左、右子树的根分别称为该结点的左孩子和右孩子。
另外,二叉树
上任一结点的度定义为该结点的孩子数(即非空子树数)。
除这几个术语之外,树的其它术
语也适用于二叉树。
特别值得注意的是,由于二叉树上任一结点的子树有左、右之分,因此即使一结点只
有一棵非空子树,仍须区别它是该结点的左子树还是右子树,这是与树不同的。
二叉树的基本运算
(1)初始化INITIATE(BT),加工型运算,其作用是设置一棵空二叉树BT=Φ
(2)求根ROOT(BT),引用型运算,其结果是二叉树BT的根结点;
若BT为空二叉
树,运算结果为一特殊标志。
(3)求双亲PARENT(BT,X),引用型运算,其结果是结点X在二叉树BT上的双亲;
若X是BT的根或X根本不是BT上的结点,运算结果为一特殊标志。
(4)求左孩子LCHILD(BT,X)和求右孩子RCHILD(BT,X),引用型运算,其结果分别
为结点X在二叉树BT上的左、右孩子;
若X为BT的叶子或X不在BT上,运算结果为
一特殊标志。
(5)建树CREAT(X,LBT,RBT),加工型运算,其作用是建立一棵以结点X为根,以
二叉树LBT、RBT分别为X的左、右子树的二叉树。
(6)剪枝DELLEFT(BT,X)和DELRIGHT(BT,X),加工型运算,其作用分别为删除二
叉树BT上结点X的左、右子树;
若X无左或右子树,运算为空操作。
与其它数据结构相同,在实际应用中根据需要对基本运算适当增减。
2.1.11二叉树的存储结构
二叉树通常有两类存储结构,顺序存储结构和链式存储结构。
二叉树的顺序存储结构
二叉树的顺序存储结构由一个一维数组构成,二叉树上的结点按某种次序分别存入该
数组的各个单元。
显然,这里的关键在于结点的存储次序,这种次序应能反映结点之间的
逻辑关系(父子关系),否则二叉树的基本运算就难以实现。
由二叉树的性质可知,若对任一完全二叉树上的所有结点按层编号,则结点编号之间
的数值关系可以准确地反映结点之间的逻辑关系。
因此,对于任何完全二叉树来说,可以
采用“以编号为地址”的策略将结点存入作为顺序存储结构的一维数组。
具体地说就是:
将编号为i的结点存入一维数组的第i个单元。
在这一存储结构中,由于一结点的存储位置(即下标)也就是它的编号,故结点间的
逻辑关系可通过它们下标间的数值关系确定。
二叉树的链式存储结构
二叉树有不同的链式存储结构,其中最常用的是二叉树链表与三叉链表。
二叉树链表的结点形式如下:
其中,data域称为数据域,用于存储二叉树结点中的数据元素;
lchild域称为左孩子指
针域,用于存放指向本结点左孩子的指针(这个指针及指针域有时简称为左指针)。
类似地,
rchild域称为右孩子指针域,用于存放指向本结点右孩子的指针(简称右指针)。
若某结点
的某个孩子不存在,则相应的指针为空。
具有n个结点的二叉树中,一共有2n个指针域,
其中只有n—1个用来指向结点的左右孩子,其余的n+1个指针域为NULL。
三叉链表的每个节点由四个域组成,其结点形式如下:
其中,data、lchild以及rchild三个域的意义同二叉链结构;
parent域为指向该结点双
亲结点的指针。
2.1.12二叉树和树的遍历
遍历是树形结构的一种重要运算。
遍历一个树形结构就是按一定的次序系统地访问该
结构中的所有结点,使每个结点恰被访问一次。
可以按多种不同的次序遍历树形结构。
2.1.13排序
排序是数据处理中经常使用的一种重要运算。
设有{R1,R2,.,Rn}是由n个记录组成的文件,其相应的关键码集合为{K1,K2,.,
Kn}。
所谓排序就是将记录按关键码值递增(或递减)的次序排列起来。
由于文件大小不同使排序过程中涉及的存储器不同,可将排序分为内部排序和外部排
序两类。
整个排序过程都在内存进行的排序,称为内排序,这是排序的基础。
内排序的方法很多,最常用的有插入排序、选择排序、交换排序和归并排序等。
2.1.14查找
查找就是在数据结构中找出满足某种条件的结点。
若从数据结构中找到满足条件的结
点,则称查找成功,否则查找失败。
衡量一个查找算法的主要标准,是查找过程中对关键
码进行的平均比较次数,或称平均检索长度,检索长度以n的函数的形式表示,n是数据
结构中的结点个数。
常用的查找算法有顺序查找、二分法查找、分块查找、散列表查找等。
parent
data
rchild
lchild
2.2重点难点
2.2.1数据的逻辑结构
数据的逻辑结构分为线性结构和非线性结构两大类,线性结构的逻辑特征是:
有且仅
有一个开始结点和一个终端结点,并且所有的结点都最多有一个直接前驱和一个直接后继。
线性表就是一个典型的线性结构,常见的线性表有顺序表、链表、栈、队列、串。
非线性
结构的逻辑特征是:
一个结点可能有多个直接前驱和直接后继。
树、二叉树、图等都是非
线性结构。
栈
栈是一种特殊的线性表,这种线性表只能在固定的一端进行插入和删除操作。
允许插
入和删除的一端称为栈顶,另一端称为栈底。
一个新元素只能从栈顶一端进入,删除时,
只能删除栈顶的元素,即刚刚被插入的元素。
由于元素是按后进先出的次序入栈和出栈的,
所以栈又称后进先出表(LastInFirstOut),简称LIFO表。
栈的基本操作有:
(1)create(s)建立一个空栈s。
(2)empty(s)测试栈是否为空栈。
(3)full(s)测试栈是否满。
(4)push(x,s)将元素x插入栈s的栈顶。
(5)top(s)取栈顶元素。
(6)pop(s)删除栈顶元素。
由于栈是一种特殊的线性表,栈的各种操作实际上是线性表的操作的特殊情形,所以
表示线性表的方法同样可以用来表示栈。
队列
队列可看作是插入在一端进行,删除在另一端进行的线性表,允许插入的一端称为队
尾,允许删除的一端称为队头。
在队列中,只能删除队头元素。
队列的最后一个元素一定
是最新入队的元素。
因此队列又称先进先出表(First-In-First-Out)。
日常生活中排队购物就是队列应用的例子:
新来的顾客排在队尾等待,排在队头的顾
客购物后离开队伍。
队列的基本操作有:
create(Q)建立一个空队列。
empty(Q)测试队列是否为空队列。
full(Q)测试队列是否为满。
front(Q)取队头元素。
enq(X,Q)向队列中插入一个元素X。
deq(Q)删除队头元素。
串
串(或字符串)是由零个或多个字符组成的有限序列,一般记为S=’a1a2.an’。
其中,
S是串的名字,用单引号括起来的若干字符是串的值。
零个字符的串是空串。
串中字符的
数目就是串的长度。
n是串中的字符,可以是字母、数字或其他字符。
空串与空格构成的
串如:
“”是不同的。
串的存储同样有顺序存储和链式存储两种。
顺序存储时,既可以采用非紧缩方式,也
可以采用紧缩方式。
串的基本运算有连接、赋值、求长度、全等比较、求子串、找子串位置以及替换等。
有些程序设计语言以标准子程序(函数或过程)方式提供了这些运算。
2.2.2数据存储结构
顺序存储结构
这种存储方式主要用于线性的数据结构,它把逻辑上相邻的数据元素存储在物理上相
邻的存储单元里,结点之间的关系由存储单元的邻接关系来体现。
顺序结构的主要特点是:
(1)结点中只有自身信息域,没有链接信息域。
因此,存储密度大,存储空间利用率
高。
(2)可以通过计算直接确定数据结构中第i个结点的存储地址Li,计算公式是:
Li=L0+(i-1)×
m
其中L0为第一个结点的存储地址,m为每个结点所占用的存储单元个数。
(3)插入、删除运算会引起大量结点的移动。
链式存储结构
链式存储结构就是在每个结点中至少包括一个指针域,用指针来体现数据元素之间逻
辑的联系。
这种存储结构,可把人们从计算机存储单元的相继性限制中解放出来,可以把
逻辑相邻的两个元素存放在物理上不相邻的存储单元中,还可以在线性编址的计算机存储
器中表示结点之间的非线性联系。
链式存储结构的主要特点是:
(1)结点中除自身信息外,还有表示链接信息的指针域,因此比顺序存储结构的存储
密小,存储空间利用率低。
(2)逻辑上相邻的结点物理上不必邻接,可用于线性表、树、图等多种逻辑结构的存
储表示。
(3)插入、删除操作灵活方便,不必移动结点,只要改变结点中的指针值即可。
散列法
散列表(又称哈希表)是线性表的一种重要存储方式和检索方法。
在散列表里可对结
点进行快速检索。
散列法的基本思想是:
由结点的关键码值决定结点的存储地址,即以关键码值k为自
变量,通过一定的函数关系h(称为散列函数),计算出对应的函数值h(k)来,把这个值
解释为结点的存储地址,将结点存入该地址中去。
检索时再根据要检索的关键码值用同样
的散列函数计算地址,然后到相应的地址中去取要找的结点。
常用的散列函数有:
(1)除余法
选择一个适当的正整数p(通常选p为不大于散列表存储区域大小的最大素数),用p
去除关键码值,取其余数作为地址。
即h(key)=keymodp。
例如,如果散列表存储区域
大小为1024,则可以选p=1019,它将关键码值5876对应到地址781,将关键码值1234
对应到地址215,.除余法地址计算公式非常简单,实践证明恰恰是这种简单的方法在许
多情况下效果较好。
(2)数字分析法
当关键码的位数比存储区域地址码位数多时,可以对关键码的各位进行分析,去掉分
布不均匀的位,留下分布均匀的位作为地址。
(3)折叠法将关键码值从某些地方断开,分为几段,折叠相加,作为地址。
(4)中平方法将关键码值平方,取中间的几位数作为地址。
在散列法中,不同的关键码值可能对应到同一存储地址,即k1≠k2,但h(k1)=h(k2)
这种现象称做碰撞(冲突)。
发生碰撞的两个或多个关键码值称做同义词。
需要有办法处理
碰撞,即为对应到同一地址的多个同义词安排存储地址。
常用的处理碰撞的方法有两类:
拉链法和开地址法。
用拉链法处理碰撞就是给散列表的每个结点增加一个link字段,当碰撞发生时利用link
字段拉链,建立链接方式的同义词子表。
每个同义词子表的第一个元素都在散列表基本区
域中。
同义词子表的其他元素存储在何处,通常采用建立溢出区的方法,即另开辟一片存
储空间作为溢出区,用于存放各同义词子表的其他元素。
用开地址法处理碰撞就是当碰撞发生时形成一个探查序列,沿着这个序列逐个地址探
查,直至找到一个开放的地址(即未被占用的单元),将发生碰撞的关键码值存人该地址中。
最简单的探查序列是线性探查,即若发生碰撞的地址为d,则探查的地址序列是:
d+1,d+2,.,m-1,0,1,.,d-1
其中,m是散列表存储区域的大小。
散列表的一个重要参数是负载因子α,它的定义是:
.ü
..?
..
数基本区域能容纳的结点
散列表中结点的数目=α
负载因子的大小体现散列表的装满程度,α越大,则散列表装得越满,发生碰撞的可
能性越大,一般取a<1。
2.2.3二叉树的性质
二叉树的性质主要有五个:
性质1
二叉树第i(i≥1)层上至多有2i-1个结点。
二叉树是结点的有限集合,这个有限集合或者为空集,或者由一个根结点及两棵不相
交的、分别称做这个根的左子树和右子树的二叉树组成。
这是一个递归的定义,二叉树的
根的左子树和右子树又都是二叉树,它们又都是结点的集合,或者为空集,或者由根结点
和左子树、右子树构成,左子树和右子树又都是二叉树,如此递归下去。
可以用归纳法证明这个性质:
当i=1时,二叉树只有一个结点,即二叉树的根结点。
显然2i-1=20=1。
假设对所有j(1≤j≤i-1)性质一成立,即第j层上最多有2i-1个结点。
证明当j=i时性质1也成立即
可。
根据归纳假设,第i-1层上最多有2i-2个结点;
又由于每个结点最多有2棵子树。
因此,
第i层的结点数目最多是第i-1层上最大结点数目的2倍,即有2×
2i-2=2i-1。
命题得证。
性质2
深度为k(k≥1)的二叉树至多有2k-1个结点。
显然,深度为k的二叉树只有是满二叉树时才能达到最大结点数,即每层的结点数目
都达到该层的最大结点数2i-1,这时二叉树的结点数目是:
1k21k112)i(.=Σ=
Σ=
.=
kiii层上结点的最大数目第
性质3