数据结构笔记


.算法的基本概念

 

.算法的复杂度

1.算法的时间复杂度:指执行算法所需要的计算工作量

2.算法的空间复杂度:执行这个算法所需要的内存空间

 

.数据结构的定义

1.数据的逻辑结构:反映数据元素之间的关系的数据元素集合的表示。数据的逻辑结构包括集合、线形结构、树形结构和图形结构四种。

2.数据的存储结构:数据的逻辑结构在计算机存储空间种的存放形式称为数据的存储结构。常用的存储结构有顺序、链接、索引等存储结构。

 

.数据结构的图形表示

在数据结构中,没有前件的结点称为根结点;没有后件的结点成为终端结点。插入和删除是对数据结构的两种基本运算。还有查找、分类、合并、分解、复制和修改等。

 

.线性结构和非线性结构

根据数据结构中各数据元素之间前后件关系的复杂程度,一般将数据结构分为两大类型:线性结构和非线性结构。

线性结构:非空数据结构满足:有且只有一个根结点;每个结点最多有一个前件,最多只有一个后件。

非线性结构:如果一个数据结构不是线性结构,称之为非线性结构。

常见的线性结构:线性表、栈、队列

 

.线性表的定义

线性表是n个元素构成的有限序列(A1A2A3……)。表中的每一个数据元素,除了第一个以外,有且只有一个前件。除了最后一个以外有且只有一个后件。

非空线性表有如下一些特征:

1)有且只有一个根结点a1,它无前件;

2)有且只有一个终端结点an,它无后件;

3)除根结点与终端结点外,其他所有结点有且只有一个前件,也有且只有一个后件。线性表中结点的个数n称为线性表的长度。当n=0时称为空表。

 

6.1线性表的顺序存储结构

线性表的顺序表指的是用一组地址连续的存储单元依次存储线性表的数据元素。

线性表的顺序存储结构具备如下两个基本特征:

1.线性表中的所有元素所占的存储空间是连续的;

2.线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。

即线性表逻辑上相邻、物理也相邻,则已知第一个元素首地址和每个元素所占字节数,则可求出任一个元素首地址

 

6.2栈及其基本运算

1. 什么是栈?栈实际上也是一个线性表,只不过是一种特殊的线性表。栈是只能在表的一端进行插入和删除运算的线性表,通常称插入、删除这一端为栈顶(TOP),另一端为栈底(BOTTOM)。当表中没有元素时称为空栈。栈顶元素总是后被插入的元素,从而也是最先被删除的元素;栈底元素总是最先被插入的元素,从而也是最后才能被删除的元素。

 

6.3.队列及其基本运算

1.什么是队列

队列是只允许在一端删除,在另一端插入的顺序表,允许删除的一端叫做对头,允许插入的一端叫做对尾。队列的修改是先进先出。往队尾插入一个元素成为入队运算。从对头删除一个元素称为退队运算。

2.循环队列及其运算

 实际应用中,队列的顺序存储结构一般采用循环队列的形式。所谓循环队列,就是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间。在循环队列中,,用队尾指针rear指向队列中的队尾元素,用排头指针front指向排头元素的前一个位置,因此,从排头指针front指向的后一个位置直到队尾指针 rear指向的位置之间所有的元素均为队列中的元素。

在实际使用循环队列时,为了能区分队满还是队列空,通常需要增加一个标志S

队列空,则S=0rear=front=m    队列满,则S=1rear=front=m

循环队列主要有两种基本运算:入队运算和退队运算

入队运算

指在循环队列的队尾加入一个新元素,首先rear=rear+1,rear=m+1时,置rear=1,然后将新元素插入到队尾指针指向的位置。当S=1rear=front,说明队列已满,不能进行入队运算,称为“上溢”。

退队运算

指在循环队列的排头位置退出一个元素并赋给指定的变量。首先front=front+1,并当front=m+1时,置front=1,然后将排头指针指向的元素赋给指定的变量。当循环队列为空S=0,不能进行退队运算,这种情况成为“下溢”。

 

6.4线性单链表的结构及其基本运算

1.线性单链表的基本概念

一组任意的存储单元存储线性表的数据元素,因此,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素ai的存储映象,成为结点。它包括两个域:其中存储数据元素信息的域称为数据域,存储直接后继存储位置的域称为指针域。指针域中存储的信息称做指针或链。n个结点链结成一个链表,即为线性表(a1, a2,……,an)的链式存储结构。又由于此链表的每个结点中只包含一个指针域,故又称线性链表或单链表。

有时,我们在单链表的第一个结点之前附设一个结点,称之为头结点,它指向表中第一个结点。头结点的数据域可以不存储任何信息,也可存储如线性表的长度等类的附加信息,头结点的指针域存储指向第一个结点的指针(即第一个元素结点的存储位置)。

在单链表中,取得第I个数据元素必须从头指针出发寻找,因此,单链表是非随机存取的存储结构  链表的形式:单向,双向

2.线性单链表的存储结构

3.带列的栈与队列

栈也是线性表,也可以采用链式存储结构。

队列也是线性表,也可以采用链式存储结构。

6.5双向链表的结构及其基本运算

在双向链表的结点中有两个指针域,其一指向直接后继,另一指向直接前驱。

6.6循环链表的结构及其基本运算

是另一种形式的链式存储结构,它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。因此,从表中任一结点出发均可找到表中其他结点。

 

7.树的定义

树是一种简单的非线性结构。树型结构的特点:

1.每个结点只有一个前件,称为父结点,没有前件的结点只有一个,称为树的根结点。

2.每一个结点可以有多个后件结点,称为该结点的子结点。没有后件的结点称为叶子结点

3.一个结点所拥有的后件个数称为树的结点度

4.树的最大层次称为树的深度。

 

7.1二叉树的定义及其基本性质

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

7.1.2二叉树的基本性质

在二叉树的第I层上至多有2i-1个结点。

深度为k的二叉树至多有2k-1个结点(k>=1)

在任意一个二叉树中,度为0的结点总是比度为2的结点多一个;

具有个结点的二叉树,其深度至少为[log2n]+1

一棵深度为k且有2k-1个结点的二叉树称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。

7.1.3满二叉树与完全二叉树

满二叉树:除最后一层以外,每一层上的所有结点都有两个子结点。在满二叉树的第K层上有2K-1个结点,且深度为M的满二叉树右2M-1个结点

完全二叉树:除最后一层以外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。具有N个结点的完全二叉树的深度为[log2n]+1

完全二叉树总结点数为N

N为奇数,则叶子结点数为(N+1/2N为偶数,则叶子结点数为N/2

7.1.4二叉树的存储结构

二叉树通常采用链式存储结构

7.1.5二叉树的遍历

就是遵从某种次序,访问二叉树中的所有结点,使得每个结点仅被访问一次。一般先左后右。

1.前序遍历DLR首先访问根结点,然后遍历左子树,最后遍历右子树。

2.中序遍历LDR首先遍历左子树,然后根结点,最后右子树

3.后序遍历LRD首先遍历左子树,然后遍历右子树,最后访问根结点。

 

8.查找

8.1顺序查找与二分查找

1.顺序查找在两种情况下只能用顺序查找:线性表为无序表、链式存储结构的有序表

2.二分查找只适用于顺序存储的有序表(从小到大)。

对于长度为N的有序线性表,在最坏情况下,二分查找只需要比较log2N次,而顺序查找要比较N次。

 

8.2交换类排序法

冒泡排序与快速排序法属于交换类的排序方法

1.冒泡排序法假设线性表的长度为N,则在最坏的情况下,冒泡排序需要经过N/2遍的从前往后的扫描和N/2遍的从后往前的扫描,需要的比较次数为NN-1/2

2.快速排序法

8.3选择类排序法 1.简单选择排序法2.堆排序法

8.4插入类排序法 1.简单插入排序法2.希尔排序法

                        最坏情况下      最好情况下     说明

 交换排序      冒泡排序     n(n-1)/2           最简单的交换排序。在待排序的元素序列基本有序的前提下,效率最高

     快速排序      n(n-1)/2     O(Nlog2 N)     

 插入排序      简单插入排序     n(n-1)/2           每个元素距其最终位置不远时适用

     希尔排序      O(n1.5)          

 选择排序      简单选择排序     n(n-1)/2          

     堆排序      O(nlog2n)           适用于较大规模的线性表

 

B- 

        是一种多路搜索树(并不是二叉的):

       1. 定义任意非叶子结点最多只有 M 个儿子;且 M>2 

       2. 根结点的儿子数为 [2, M] 

       3. 除根结点以外的非叶子结点的儿子数为 [M/2, M] 

       4. 每个结点存放至少 M/2-1 (取上整)和至多 M-1 个关键字;(至少 2 个关键字)

       5. 非叶子结点的关键字个数 = 指向儿子的指针个数 -1 

       6. 非叶子结点的关键字: K[1], K[2], …, K[M-1] ;且 K[i] < K[i+1] 

       7. 非叶子结点的指针: P[1], P[2], …, P[M] ;其中 P[1] 指向关键字小于 K[1] 的子树, P[M] 指向关键字大于 K[M-1] 的子树,其它P[i] 指向关键字属于 (K[i-1],K[i]) 的子树;

       8. 所有叶子结点位于同一层;

        如:( M=3 

      ‍ 

      B- 树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

B- 树的特性:

       1. 关键字集合分布在整颗树中;

       2. 任何一个关键字出现且只出现在一个结点中;

       3. 搜索有可能在非叶子结点结束;

       4. 其搜索性能等价于在关键字全集内做一次二分查找;

       5. 自动层次控制;

        由于限制了除根结点以外的非叶子结点,至少含有 M/2 个儿子,确保了结点的至少利用率,其最底搜索性能为:

              

        其中, M 为设定的非叶子结点最多子树个数, N 为关键字总数;

        所以 B- 树的性能总是等价于二分查找(与 M 值无关),也就没有 B 树平衡的问题;

        由于 M/2 的限制,在插入结点时,如果结点已满,需要将结点分裂为两个各占 M/2 的结点;删除结点时,需将两个不足 M/2 的兄弟结点合并;

 

B+ 

       B+ 树是 B- 树的变体,也是一种多路搜索树:

       1. 其定义基本与 B- 树同,除了:

       2. 非叶子结点的子树指针与关键字个数相同;

       3. 非叶子结点的子树指针 P[i] ,指向关键字值属于 [K[i],K[i+1]) 的子树( B- 树是开区间);

       5. 为所有叶子结点增加一个链指针;

       6. 所有关键字都在叶子结点出现;

        如:( M=3 

      ‍ 

    B+ 的搜索与 B- 树也基本相同,区别是 B+ 树只有达到叶子结点才命中( B- 树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

       B+ 的特性:

       1. 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

       2. 不可能在非叶子结点命中;

       3. 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

       4. 更适合文件索引系统;

   

B* 

         B+ 树的变体,在 B+ 树的非根和非叶子结点再增加指向兄弟的指针;

      ‍ 

    B* 树定义了非叶子结点关键字个数至少为 (2/3)*M ,即块的最低使用率为 2/3 (代替 B+ 树的 1/2 );

       B+ 树的分裂:当一个结点满时,分配一个新的结点,并将原结点中 1/2 的数据复制到新结点,最后在父结点中增加新结点的指针;B+ 树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

       B* 树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制 1/3 的数据到新结点,最后在父结点增加新结点的指针;

        所以, B* 树分配新结点的概率比 B+ 树要低,空间使用率更高;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值