数据结构期末复习(江财版)

不包含任何代码,纯文字版归纳总结。

绪论

数据:所有能被输入到计算机并被处理的符号的集合

数据元素:数据的基本单位

数据项:构成数据的不可分割的最小单位,一个数据元素有若干个数据项组成。

数据对象:相同性质的数据元素的集合,是数据的一个子集。

数据类型:一个值的集合和定义在这个集合上的一组操作的总成。

原子类型:值不可在分割的数据类型。

结构类型:值不可在分解成若干的数据类型。

抽象数据类型:抽象数据组织和与之相关的操作。

抽象数据类型(ADT):一个数学模型以及定义在该模型上的一组操作。其定义只与逻辑特性有关,通常采用(数据对象,数据关系,基本操作集)这样的三元来表示抽象数据类型。

数据结构:相互之间存在的一种或多种特定关系的数据元素的集合,包括:逻辑结构,存储结构和数据的运算。

数据的三要素:逻辑结构,物理结构,数据元素。

数据的逻辑结构:数据元素之间的逻辑关系。

数据的逻辑结构分类图:

四种基本结构:

1.集合:结构中的数据元素之间除了“同属一个集合”的关系之外,没有任何关系。

2.线性结构:结构中的数据元素之间只存在一对一的关系。

3.树形结构:结构中的数据元素之间存在一对多的关系。

4.图状结构或网状结构:结构中的数据元素之间存在多对多的关系。

数据的存储结构:数据结构在计算机中的表示,也称物理结构。

顺序存储:把逻辑上相邻的元素存储在物理位置上相邻的存储单元里,通过存储单元的邻接关系来表示元素之间的逻辑关系。

优点:实现随机存储,每个元素占用空间小。

缺点:只能使用相邻的一整块存储单元,会产生较多的外部碎片。

链式存储:不要求逻辑上相邻的元素在物理位置上也相邻,通过指针表示元素之间的逻辑关系。

优点:不会出现碎片现象,充分利用所有的存储单元。

缺点:每个元素要占用存储指针,需要多占用部分存储空间,而且只能顺序存取。

算法的基本概念:

 算法对特定问题求解步骤的一种描述,它是指令的有限序列,期中每一条指令都表示一个或多个操作。

算法的5个重要性:有穷性,确定性,可行性,输入,输出。

算法设计的要求:正确性,可读性,健壮性,效率与低存储需求。

算法效率的度量:通常用时间复杂度和空间复杂度来描述。

时间复杂度:算法中所有语句的频度(指该语句在算法中被重复执行的次数)之和记作T(n),时间复杂度主要分析T(n)的数量级。

算法中的基本运算(最深层循环内的语句)的频度与T(n)同数量级,所以一般采用算法中最基本的频度f(n)来分析算法时间复杂的度。即T(n)=O(f(n))

空间复杂度:算法耗费的存储空间,记作S(n)=O(g(n))

算法原地工作指算法所需要辅助空间是常量,即O(1)

.线性表的定义和基本操作

线性表的定义:具有相同数据类型的n(N>=0)个数据元素的有限序列。N=0时为空表。

线性表的特点:

1.除第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素外,每个元素有且仅有一个直接后继

2.表中元素个数有限

3.表中元素具有逻辑上的顺序关系

4.表中每个元素都是数据元素,每个元素都是单个元素

5.表中元素的数据类型都相同,即每个元素占有相同大小的存储空间

6.表中元素具有抽象性,即只关注与逻辑结构,不关注于元素表示的内容

7.线性表示一种逻辑结构 ,表示元素之间一对一的相邻关系;顺序表和链表是存储结构,表示物理结构。

线性表的顺序存储结构是一种随机存取的存储结构。

1、随机存取就是直接存取,可以通过下标直接访问的那种数据结构,与存储位置无关。例如数组。

​ 非随机存取就是顺序存取,不能通过下标访问了,只能按照存储顺序存取,与存储位置有关,例如链表。

2、顺序存取就是存取第N个数据时,必须先访问前(N-1)个数据 (list);

​ 随机存取就是存取第N个数据时,不需要访问前(N-1)个数据,直接就可以对第N个数据操作 (array)。

线性表分为顺序表和链表:

1.每个存储结点都包含两部分:数据域和指针域(链域)

2.在单链表中,除了首元结点外,任一结点的存储位置由 其直接前驱结点的链域的值 指示。  

3.在链表中设置头结点有什么好处?

    头结点即在链表的首元结点之前附设的一个结点,该结点的数据域可以为空,也可存放

表长度等附加信息,其作用是为了对链表进行操作时,可以对空表、非空表的情况以及对首

元结点进行统一处理,编程更方便。

4.如何表示空表?

(1)无头结点时,当头指针的值为空时表示空表;

(2)有头结点时,当头结点的指针域为空时表示空表。

存储密度=数据元素本身占用的存储量\结点结构占用的存储量

三.栈和队列

1.栈和队列属于逻辑结构而非存储结构,它们的实现才属于存储结构。

2.栈的定义:只允许一端进行插入和删除操作的线性表

栈顶:栈允许进行插入和删除的那一端

栈底:固定的,不允许进行插入和删除的一端。

栈是一个先进后出的线性表

3.顺序栈栈空条件:S.top=-1;(top=base)栈满条件:S.top=MaxSize-1;栈长:S.top+1

4.链栈:采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现,并规定所有操作都是在单链表的表头进行的。这里规定链栈没有头节点,Lhead指向栈顶元素。

5.链栈的进栈push和出栈pop操作都很简单,时间复杂度均为O(1)。

对比一下顺序栈与链栈,它们在时间复杂度上是一样的,均为O(1)。对于空间性能,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,但它的优势是存取时定位很方便,而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制。所以它们的区别和线性表中讨论的一样,如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。

6.递归算法,斐波那契数列和汉诺塔时间复杂度均为o(2^n),空间复杂度o(n).

7.中缀表达式不仅依赖运算符的优先级,而且还要处理括号。后缀表达式的运算符在操作数后面,在后缀表达式中已考虑了运算符的优先级,没有括号,只有操作数和运算符。例如中缀表达式A + B ∗ ( C − D ) − E / F 所对应的后缀表达式为A B C D − ∗ + E F / − 。

后缀表达式计算规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进项运算,运算结果进栈,一直到最终获得结果。

8.队列的定义:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出的线性表,允许插入的一端称为队尾,允许删除的一端称为队头。

队头(Front):允许删除的一端,又称队首。
队尾(Rear):允许插入的一端。
空队列:不包含任何元素的空表。

9.队列的顺序存储结构:队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针 front指向队头元素,队尾指针 rear 指向队尾元素的下一个位置。

10.初始状态(队空条件):Q->front == Q->rear == 0。
进队操作:队不满时,先送值到队尾元素,再将队尾指针加1。
出队操作:队不空时,先取队头元素值,再将队头指针加1。

11.循环队列:解决假溢出的方法就是后面满了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。

当队首指针Q->front = MAXSIZE-1后,再前进一个位置就自动到0,这可以利用除法取余运算(%)来实现。

初始时:Q->front = Q->rear=0。

队首指针进1:Q->front = (Q->front + 1) % MAXSIZE。

队尾指针进1:Q->rear = (Q->rear + 1) % MAXSIZE。

队列长度:(Q->rear - Q->front + MAXSIZE) % MAXSIZE。

12.为了区分队空还是队满的情况,有三种处理方式:

(1)牺牲一个单元来区分队空和队满,入队时少用一个队列单元,这是种较为普遍的做法,约定以“队头指针在队尾指针的下一位置作为队满的标志”,如图 ( d2 )所示。

队满条件: (Q->rear + 1)%Maxsize == Q->front

队空条件仍: Q->front == Q->rear

队列中元素的个数: (Q->rear - Q ->front + Maxsize)% Maxsize

(2)类型中增设表示元素个数的数据成员。这样,队空的条件为 Q->size == O ;队满的条件为 Q->size == Maxsize 。这两种情况都有 Q->front == Q->rear

(3)类型中增设tag 数据成员,以区分是队满还是队空。tag 等于0时,若因删除导致 Q->front == Q->rear ,则为队空;tag 等于 1 时,若因插入导致 Q ->front == Q->rear ,则为队满。

13.链队列:队列的链式存储结构表示为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表,只不过它只能尾进头出而已。空队列时,front和real都指向头结点。

当Q->front == NULL 并且 Q->rear == NULL 时,链队列为空。

14.表达式求值,括号匹配算法时间和空间复杂度均为o(n),数制转换的均为o(log8N)

四.串

1.串( string)是由零个或多个字符组成的有限序列,又名叫字符串。

一般记为:S = ′ a 1 a 2 . . . a n ′  (n>=0)。

其中,S是串名,单引号括起来的字符序列是串的值; An可以是字母、数字或其他字符;串中字符的个数n称为串的长度。

串的数据元素是单个字符!串的长度是串中所含字符个数。

另外还有一些其它概念:

空串:n = 0时的串称为空串。

空格串:是只包含空格的串。注意它与空串的区别,空格串是有内容有长度的,而且可以不止一个空格。

子串与主串:串中任意个数的连续字符组成的子序列称为该串的子串,相应地,包含子串的串称为主串。

子串在主串中的位置就是子串的第一个字符在主串中的序号。

串的逻辑结构和线性表极为相似,区别仅在于串的数据对象限定为字符集。在基本操作上,串和线性表有很大差别。线性表的基本操作主要以单个元素作为操作对象,如查找、插入或删除某个元素等;而串的基本操作通常以子串作为操作对象,如查找、插入或删除一个子串等。

2.串的存储结构

顺序存储表示:

类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。在串的定长顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。

串都是从下标为1的数组分量开始储存。

这种定义方式是静态的,在编译时刻就确定了串空间大小。

3.串的链式存储表示

类似于线性表的链式存储结构,也可采用链表方式存储串值。由于串的特殊性(每个元素只有一个字符),在具体实现时,每个结点既可以存放一个字符, 也可以存放多个字符。

结点大小的选择直接影响串的处理效率。存储密度小时,运算处理方便,存储占用量大。

BF算法(串的定长顺序存储结构)

最好情况下时间复杂度o(m+n)

最坏情况下时间复杂度o(m*n)

  • 树和二叉树

1.树的定义

树是n(n>=0)个结点的有限集。当n = 0时,称为空树。在任意一棵非空树中应满足:

①有且仅有一个特定的称为根的结点。

②当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每个集合本身又是一棵树,并且称为根的子树。

显然,树的定义是递归的,即在树的定义中又用到了自身,树是一种递归的数据结构。树作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点:

①树的根结点没有前驱,除根结点外的所有结点有且只有一个前驱。

②树中所有结点可以有零个或多个后继。

因此n个结点的树中有n-1条边。

2.树中一个结点的孩子个数称为该结点的度,树中结点的最大度数称为树的度。度大于0的结点称为分支结点(又称非终端结点);度为0(没有子女结点)的结点称为叶子结点(又称终端结点)。在分支结点中,每个结点的分支数就是该结点的度。

3.结点的深度是从根结点开始自顶向下逐层累加的。
结点的高度是从叶结点开始自底向上逐层累加的。
树的高度(或深度)是树中结点的最大层数。

4.路径和路径长度。树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成的,而路径长度是路径上所经过的边的个数。
注意:由于树中的分支是有向的,即从双亲指向孩子,所以树中的路径是从上向下的,同一双亲的两个孩子之间不存在路径。

5.树具有如下最基本的性质:

树中的结点数等于所有结点的度数加1.

度为m 的树中第i层上至多有m^(i − 1)个结点(i > = 1 )

高度为h 的m 叉树至多有( m^h − 1 ) / ( m − 1 ) 个结点。

具有n 个结点的m叉树的最小高度为[ l o g m ( n ( m − 1 ) + 1 ) ] 。

6.二叉树的定义

二叉树是另一种树形结构,其特点是每个结点至多只有两棵子树( 即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。

与树相似,二叉树也以递归的形式定义。二叉树是n (n≥0) 个结点的有限集合:

或者为空二叉树,即n=0。

或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一棵二叉树。

二叉树是有序树,若将其左、右子树颠倒,则成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。

7.满二叉树:

一棵高度为h,且含有2 h − 1 个结点的二叉树称为满二叉树,即树中的每层都含有最多的结点。满二叉树的叶子结点都集中在二叉树的最下一层,并且除叶子结点之外的每个结点度数均为2。可以对满二叉树按层序编号:约定编号从根结点(根结点编号为1 )起,自上而下,自左向右。这样,每个结点对应一个编号,对于编号为i的结点,若有双亲,则其双亲为i / 2 ,若有左孩子,则左孩子为2 i;若有右孩子,则右孩子为2 i + 1 。

8.完全二叉树

高度为h 、有n n个结点的二叉树,当且仅当其每个结点都与高度为h的满二叉树中编号为1~n的结点一一对应时,称为完全二叉树,如图所示。其特点如下:

①若i ≤ n / 2 , 则结点i 为分支结点,否则为叶子结点。

②叶子结点只可能在层次最大的两层上出现。对于最大层次中的叶子结点,都依次排列在该层最左边的位置上。

③若有度为1 的结点,则只可能有一个,且该结点只有左孩子而无右孩子(重要特征)。

④按层序编号后,一旦出现某结点(编号为i )为叶子结点或只有左孩子,则编号大于i的结点均为叶子结点。

⑤若n 为奇数,则每个分支结点都有左孩子和右孩子;若n为偶数,则编号最大的分支结点(编号为n / 2)只有左孩子,没有右孩子,其余分支结点左、右孩子都有。

9.二叉排序树

左子树上所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。

10.平衡二叉树

树上任一结点的左子树和右子树的深度之差不超过1。

11.二叉树的性质

①任意一棵树,若结点数量为n ,则边的数量为n − 1 。

②非空二叉树上的叶子结点数等于度为2的结点数加1,即n0= n 2 + 1

③非空二叉树上第k 层上至多有2^k − 1 个结点( k ≥ 1 ) 。

④高度为h的二叉树至多有2^h-1个结点( h ≥ 1 )。

⑤对完全二叉树按从上到下、从左到右的顺序依次编号1 , 2.. ∗ , n 则有以下关系:

1)i > 1时,结点i 的双亲的编号为i / 2 ,即当i 为偶数时,它是双亲的左孩子;当i为奇数时,它是双亲的右孩子。

2)当2 i ≤ n时,结点i ii的左孩子编号为2 i  否则无左孩子。

3)当2 i + 1 ≤ n 时,结点i 的右孩子编号为2 i + 1,否则无右孩子。

4)结点i 所在层次(深度)为{ l o g 2 i } + 1

⑥具有n 个( n > 0 )结点的完全二叉树的高度为{ l o g 2 n } + 1

⑦一颗完全二叉树结点数为n,则其父结点数为n/2,叶子结点数为n-n/2。

⑧一颗深度为7的完全二叉树第七层有11个叶结点,则二叉树有?个叶结点。

第六层最后一个编号为63,第七层第11个编号为74,父结点为74/2=37,叶结点为74-37=37。

⑨一颗满二叉树有A个叶结点,B个结点,深度为C。B=2A-1,B=2^c-1

12.在含有n个结点的二叉链表中,含有n + 1 个空链域

13.遍历二叉树:二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。

时间复杂度都是O(n),空间复杂度都是O(n)

15.由二叉树的先序序列和中序序列可以唯一地确定一棵二叉树。

由二叉树的后序序列和中序序列也可以唯一地确定一棵二叉树。

由二叉树的层序序列和中序序列也可以唯一地确定一棵二叉树。

16.森林化为二叉树的规则:第一个孩子为左孩子,兄弟为右孩子。

17.哈夫曼树的定义和原理:在许多应用中,树中结点常常被赋予一个表示某种意义的数值,称为该结点的权。从树的根到任意结点的路径长度(经过的边数)与该结点上权值的乘积,称为该结点的带权路径长度。树中所有叶结点的带权路径长度之和称为该树的带权路径长度,记为WPL=i=1∑n​wi​li                                                                wi是第i个叶结点所带的权值,l i是该叶结点到根结点的路径长度。

在含有n个带权叶结点的二叉树中,其中带权路径长度(WPL)最小的二叉树称为哈夫曼树,也称最优二叉树。

18.前缀编码:如果在一个编码方案中,任一个编码都不是其他任何编码的前缀(最左子串),则称编码是前缀编码。前缀编码可以保证对压缩文件进行解码时不产生二义性,确保正确解码。哈夫曼编码是最优前缀编码。

1.图(Graph)是由顶点的有穷非空集合V ( G )和顶点之间边的集合E ( G ) 组成,通常表示为: G = ( V , E ),其中,G 表示个图,V 是图G 中顶点的集合,E是图G 中边的集合。若V = { v 1 , v 2 , . . . , v n } ,则用 |V|表示图G 中顶点的个数,也称图G 的阶,E = { ( u , v ) ∣ u ∈ V , v ∈ V },用∣E∣表示图G 中边的条数。

线性表可以是空表,树可以是空树,但图不可以是空图。就是说,图中不能一个顶点也没有,图的顶点集V一定非空,但边集E可以为空,此时图中只有顶点而没有边。

2.有向图

若E是有向边(也称弧)的有限集合时,则图G为有向图。弧是顶点的有序对,记为<v, w>,其中v,w是顶点,v称为弧尾,w称为弧头,<v,w>称为从顶点v到顶点w的弧,也称v邻接到w,或w邻接自v。

3.无向图

若E是无向边(简称边)的有限集合时,则图G为无向图。边是顶点的无序对,记为(v, w)或(w,v),因为(v,w)=(w,v), 其中v,w是顶点。可以说顶点w和顶点v互为邻接点。边(v, w)依附于顶点w和v,或者说边(v, w)和顶点v, w相关联。

4.简单图:一个图G若满足:①不存在重复边;②不存在顶点到自身的边,则称图G为简单图。

多重图:若图G中某两个结点之间的边数多于一条,又允许顶点通过同一条边和自己关联,则G为多重图。多重图的定义和简单图是相对的。

看书P150-151

  1. 图的存储结构:邻接矩阵,邻接表P153
  2. 图的应用P165

  • 查找

1.查找(Searching):就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素( 或记录)。

查找表(Search Table):是由同一类型的数据元素(或记录)构成的集合。

关键字(Key):数据元素中唯一标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的。例如,在由一个学生元素构成的数据集合中,学生元素中“学号”这一数据项的值唯一地标识一名学生。

2.静态查找表(Static Search Table):只作查找操作的查找表。

主要操作:①查询某个“特定的”数据元素是否在查找表中。

②检索某个“特定的”数据元素和各种属性。

动态查找表(Dynamic Search Table): 在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。

主要操作:①查找时插入不存在的数据元素。

②查找时删除已存在的数据元素。

3.平均查找长度:在查找过程中,一次查找的长度是指需要比较的关键字次数,而平均查找长度,则是所有查找过程中进行关键字的比较次数的平均值,其数学定义为ASL=i=1∑n​Pi​Ci

n是查找表的长度;Pi是查找第i个数据元素的概率,一般认为每个数据元素的查找概率相等,即Pi = 1 / n;Ci是找到第i个数据元素所需进行的比较次数。平均查找长度是衡量查找算法效率的最主要的指标。

4.顺序表查找:顺序查找时间复杂度o(n),优点:算法简单,对表结构无任何要求,既适用于顺序结构,也适用于链式结构,无论顺序按关键字是否有序均可应用。缺点:平均查找长度大,查找效率低,当n很大时,不宜使用顺序查找。

5.有序表查找:折半(二分)查找,必须采用顺序存储结构!链式不行!(p195)

折半查找的基本思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

折半查找的过程可用二叉树来描述,称为判定树。

我们知道,具有n个结点的二叉树的深度为⌈ l o g 2 ( n + 1 ) ⌉,所以,折半查找的时间复杂度为O(log2n)平均情况下比顺序查找的效率高。

优点:比较次数少,查询效率高。

缺点:对表要求高,只能用于顺序存储的有序表。不适用于数据元素经常变动的线性表。

6.分块查找:对数据集进行分块,使其分块有序,然后再对每一块建立一个索引项,从而减少索引项的个数。

分块有序,是把数据集的记录分成了若千块,并且这些块需要满足两个条件:

①块内无序:即每一块内的记录不要求有序。

②块间有序:例如,要求第二块所有记录的关键字均要大于第一块中所有记录的关键字,第三块的所有记录的关键字均要大于第二块的所有记录关键字…因为只有块间有序,才有可能在查找时带来效率。

分块查找的平均查找长度为索引查找和块内查找的平均长度之和。设索引查找和块内查找的

平均查找长度分别为L I , L S ,则分块查找的平均查找长度为:ALS=LI​+LS

我们假设,将长度为n的查找表均匀地分为b 块,每块有s 个记录,即b = n / s,在等概率情况下,若在块内和索引表中均采用顺序查找,则平均查找长度为:

ASL=LI+LS=(b+1)/2+(s+1)/2=(s2+2s+n)/2s

此时平均查找长度不仅和表长n有关,而且和每块中记录个数s有关。在给定n前提下,s是可以选择的。

分块查找优点:在表中插入和删除元素时,只要找到该元素对应的块,就可以在该元素块内进行插入和删除运算。由于块内是无序的,插入和删除比较容易,无需大量移动。如果线性表既要快速查找又要经常动态变化,则可使用分块查找。缺点:要增加一个索引表存储空间并对初始索引表进行排序运算。

7.线性表的查找(以上三个)更适用于静态查找表,若要对动态查找表进行高效率查找,可采用二叉排序树和平衡二叉树。

8.二叉排序树(也称二叉查找树)或者是一棵空树,或者是具有下列特性的二叉树:

①若左子树非空,则左子树上所有结点的值均小于根结点的值。

②若右子树非空,则右子树上所有结点的值均大于根结点的值。

③左、右子树也分别是一棵二叉排序树。

二叉排序树的优点明显,插入删除的时间性能比较好。而对于二叉排序树的查找,走的就是从根结点到要查找的结点的路径,其比较次数等于给定值的结点在二叉排序树的层数。极端情况,最少为1次,即根结点就是要找的结点,最多也不会超过树的深度。也就是说,二叉排序树的查找性能取决于二叉排序树的形状。

二叉排序树平均查找长度o(log2n),查找、插入、删除时间复杂度都为o(log2n)。

对于需要经常进行插入、删除和查找运算的表,用二叉排序树比较好。

9.平衡二叉树:是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。

它是一种高度平衡的二叉排序树。它要么是一棵空树, 要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。我们将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF (Balance Factor) , 那么平衡二叉树上所有结点的平衡因子只可能是-1、0和1。只要二叉树上有一个结点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。

平衡二叉树的平均查找长度为O(log2n)。

10.散列表查找的基本概念

散列表是根据关键字而直接进行访问的数据结构。也就是说,散列表建立了关键字和存储地址之间的一种直接映射关系。我们只需要通过某个函数f,使得:存储位置 = f (关键字)

那样我们可以通过查找关键字不需要比较就可获得需要的记录的存储位置。

散列技术既是一种存储方法, 也是一种查找方法,散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。查找时,根据这个确定的对应关系找到位置上。

这里我们把这种对应关系f 称为散列函数,又称为哈希(Hash)函数。按这个思想,采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)。那么关键字对应的记录存储位置我们称为散列地址。

散列函数可能会把两个或两个以上的不同关键字映射到同一地址,称这种情况为冲突,这些发生碰撞的不同关键字称为同义词。一方面,设计得好的散列函数应尽量减少这样的冲突;另一方面,由于这样的冲突总是不可避免的,所以还要设计好处理冲突的方法。

理想情况下,对散列表进行查找的时间复杂度为O(1),即与表中元素的个数无关。

11.除留余数法:这是一种最简单、最常用的方法,假定散列表表长为m,取一个不大于m但最接近或等于m的质数p,利用以下公式把关键字转换成散列地址。散列函数为H(key)=key%p  (p<=m)

这方法不仅可以对关键字直接取模,也可在折叠、平方取中后再取模。

除留余数法的关键是选好p,使得每个关键字通过该函数转换后等概率地映射到散列空间上的任一地址,从而尽可能减少冲突的可能性。

12.处理散列冲突

开放定址法:所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。

在处理过程中发生的两个第一个散列地址不同的记录争夺同一个后继散列地址的现象称为“二次聚集”。

13.散列表的查找效率取决于三个因素:散列函数、处理冲突的方法和装填因子。散列表的装填因子一般记为α,定义为一个表的装满程度,即α=n(表中记录数)​/m(散列表长度)

散列表的平均查找长度依赖于散列表的装填因子α ,而不直接依赖于n或m。直观地看,α 越大,表示装填的记录越“满”,发生冲突的可能性越大,反之发生冲突的可能性越小。

  • 排序

1.排序的稳定性。假设k i = k j ( 1 ≤ i ≤ n , 1 ≤ j ≤ n , i ! = j ),且在排序前的序列中R i 领先于R j (即i < j)。如果排序后R i 仍领先于R j,则称所用的排序方法是稳定的;反之,若可能使得排序后的序列中R j 领先于R i,则称所用的排序方法是不稳定的。

2.内排序和外排序。内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中。外排序是由于排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。

3.内部排序算法的性能取决于算法的时间复杂度和空间复杂度,而时间复杂度一般是由比较和移动的次数决定的。空间复杂度由辅助空间决定,辅助空间是除了存放待排序记录占用的空间之外,执行算法所需要的其他存储空间。

4.直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。

具体的看书,要写排序步骤。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值