【软件测评师】04数据结构与算法基础知识

#用于个人笔记整理

一、数据结构的概述

1、数据结构的概念

数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。常见的数据结构有:数组、栈、队列、链表、树、图、堆、散列表等。每种数据结构都有其特定的应用场景和优势。

2、逻辑结构、物理结构

1)物理存储结构

  物理存储结构(也称数据的物理结构):是指数据的逻辑结构在计算机存储空间的存放形式。数据的物理结构是数据结构在计算机中的表示(又称映像),它包括数据元素的表示和关系的表示。它主要关注如何将数据元素存储到计算机的存储器中,以及如何在存储器中实现数据元素的逻辑结构。数据的物理结构主要包括顺序存储结构和链式存储结构两种基本类型。数据的物理结构主要包括顺序存储结构和链式存储结构两种基本类型。

(1)顺序存储结构:是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。顺序存储结构是一种最基本的存储表示方法,通常借助于程序语言的数组实现。

(2)链式存储结构:是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的。数据元素的存储关系并不能反映其逻辑关系,因此需要用一个指针存放数据元素的地址,这样通过地址就可以找到相关联数据元素的位置。链式存储结构通常借助于程序语言的指针类型实现。

2)逻辑结构

逻辑结构:是指数据元素之间的逻辑关系,即从逻辑关系上描述数据。它与数据的存储无关,是独立于计算机的。数据结构的逻辑结构主要分为线性结构和非线性结构两大类。

(1)线性结构:线性结构中的数据元素之间存在一对一的关系,每一个节点有唯一的前续和后继。常见的线性结构包括线性表、栈、队列和串。线性表是最简单、最基本、最常用的数据结构,是有序数据元素的集合。

(2)非线性结构:非线性结构中的数据元素之间存在一对多或多对一的关系。常见的非线性结构包括树和图。树是一种具有层次关系的数据结构,它由一个根节点和若干个子树组成。图则是由顶点和边组成的数据结构,其中顶点表示对象,边表示对象之间的关系。

二、线性表

1、线性表的基本概念

1)顺序表

顺序表是一种线性表,它以连续的内存空间存储数据,并按照一定的顺序进行访问。顺序表的特点是元素在内存中的地址是连续的,通过元素的下标可以快速访问和操作数据。顺序表在插入和删除操作时需要搬移后面的所有元素,因此效率较低,但其支持随机访问,访问元素的时间复杂度为O(1)。顺序表在扩容时需要开辟新空间,拷贝元素,并释放旧空间。

2)链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点组成,每个结点包括存储数据元素的数据域和存储下一个结点地址的指针域。链表可以在运行时动态生成结点,克服了数组链表需要预先知道数据大小的缺点,并实现了灵活的内存动态管理。链表在插入和删除操作时可以达到O(1)的复杂度,但在查找一个节点或访问特定编号的节点时则需要O(n)的时间。链表不支持随机访问,且由于增加了结点的指针域,空间开销较大。

单链表是链表的一种形式,每个结点只有一个指向下一个结点的指针,因此只能单向遍历。循环链表与单链表类似,但循环链表的最后一个结点指向头结点,形成一个闭环,使得链表可以从任意位置开始遍历。

双向链表是另一种链表形式,每个结点有两个指针域,一个指向直接后继,另一个指向直接前驱。这使得双向链表可以双向遍历,克服了单链表和循环链表只能单向遍历的缺点。

三、队列与栈

1、队列与栈的基本概念

栈(stack)是一种后进先出(LIFO)的数据结构,只允许在一端进行插入和删除操作,这一端被称为栈顶,另一端被称为栈底。栈的主要操作包括入栈(push),即将新元素压入栈顶;出栈(pop),即将栈顶元素弹出;以及查看栈顶元素等。栈的应用场景广泛,例如用于实现函数调用和递归、撤销操作、浏览器的前进后退功能等。

队列(queue)则是一种先进先出(FIFO)的数据结构,它有两个端点:队头和队尾。新元素总是添加到队尾,而读取或删除操作总是在队头进行。队列的主要操作包括入队(enqueue),即在队尾添加新元素;出队(dequeue),即从队头移除元素;以及查看队头或队尾元素等。队列常用于管理需要按照特定顺序处理的元素,例如在网络流量控制、消息传递、打印任务排队等场景中。

考法1: 栈的出入栈序列

题目:设元素a、b、c、d依次进入一个初始为空的栈,则不可能通过合法的栈操作序列得到 (C)

A.abcd

B.bacd

C.cabd

D.dcba

解析:枚举出每种可能排查选项

四、数组

1、数组的存储

存储地址计算:

数组按行优先存储和按列优先存储是数组在内存中存储元素的两种不同顺序。

数组的下标是从0开始的。

考点一:数组元素的偏移量/地址计算

题目:设数组a[1..10,1..8]中的元素按行存放,每个元素占用4个存储单元,已知第一个数组元素a[1,1]的地址为1004,那么a[5,6]的地址为

答案:1004+(5*10+6-1)*4

解析:a[1..10,1..8]表明数组下标从1开始计算,共10行8列,元素按行存放,a[5,6]是第5*10+6个元素,和a[1,1]相差5*10+6-1个元素,一个元素占用4个存储单元,在地址1004后面需要加(5*10+6-1)*4

五、树与二叉树

1、树的基础概念

结点的度:一个结点含有的子结点的个数称为该结点的度。

树的高度或深度:树中结点的最大层次。

叶子结点或终端结点:度为0的结点称为叶结点或终端结点,即没有子结点的结点。

分支结点或非终端结点:度不为0的结点称为分支结点或非终端结点,即具有子结点的结点。

内部结点:除了根结点和叶子结点外的所有结点。

父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点。

子结点:一个结点含有的子树的根结点称为该结点的子结点。

兄弟结点:具有相同父结点的结点互称为兄弟结点。

层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推。

二叉树(Binary Tree):二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。每个节点包含一个数据元素以及两个指向其子节点的指针(或链接)。如果某个节点没有子节点,那么相应的指针就是空的(或称为null)。

满二叉树(Full Binary Tree):满二叉树是一种特殊的二叉树,其所有非叶子节点都有两个孩子(即度为2),并且所有叶子节点都在同一层上。满二叉树的每一层都是完全填满的,即没有空闲的节点位置。

完全二叉树(Complete Binary Tree):完全二叉树也是一种特殊的二叉树,它的特点是:除了最后一层外,每一层上的节点数都达到最大值;在最后一层上只缺少右边的若干节点(即叶子节点都在最右边)。完全二叉树是从满二叉树中删除若干层最右边的节点而得到的。

考点一:二叉树的特性

题目:对下图所示的二叉树进行顺序存储 (根结点编号为1,对于编号为i的结点,其左孩子结点为21,右孩子结点为2i+1) 并用一维数组BT来表示,已知结点X、E和D在数组BT中的下标分别为1、2、3,可推出结点G、K和H在数组BT中的下标分别为11、22、23

解析:

2、二叉树的遍历

先序遍历:根左右 12457836

中序遍历:左根右 42785136

后序遍历:左右根 48752631

层次遍历(广度优先算法):从上到下从左往右12345678

 

考点二:二叉树的遍历

题目:

解析:先序遍历:C、D符合,中序遍历:D符合

答案:D

六、堆

1、堆的基本概念

堆(Heap)是一类特殊的数据结构,通常可以被看作一棵完全二叉树的数组对象。

堆中某个结点的值总是不大于或不小于其父结点的值。根据堆顶元素的大小,堆分为最大堆和最小堆。最大堆的堆顶元素是最大的,而最小堆的堆顶元素是最小的。

考点一:大小顶堆

题目:堆是一种数据结构,分为大顶堆和小顶堆两种类型,大 (小)顶堆要求父元素大于等于 (小于等于) 其左右孩子元素。则(A)是一个大顶堆结构(层次遍历),该堆结构用二叉树表示,其高度(或层数) 为3

A. 94,31,53,23,16,27

B. 94,53,31,72,16,23

C. 16,53,23,94,31,72

D.16,31,23,94,53,72

解析:堆是完全二叉树,大堆父节点的元素大小比子节点的大,A符合要求

七、图

1、图的基本概念

在计算机科学、图论和许多其他领域中,图(Graph)是一个非常重要的数据结构,用于表示对象之间的关系。图由顶点(或节点)和边组成,其中边表示顶点之间的连接关系。根据边是否有方向,图可以分为有向图(Directed Graph)和无向图(Undirected Graph)。

无向图(Undirected Graph):在无向图中,边没有方向。也就是说,如果两个顶点之间存在一条边,那么它们之间的连接是双向的。无向图通常使用不带箭头的线段来表示边。

有向图(Directed Graph):在有向图中,边具有方向。也就是说,如果两个顶点之间存在一条边,那么这条边只能从一个顶点指向另一个顶点。有向图通常使用带箭头的线段来表示边,箭头从起始顶点指向终止顶点。

在无向图中,一个顶点的度(Degree)是指与该顶点直接相连的边的数量。换句话说,它是该顶点邻接顶点的数量。

在有向图中,一个顶点的入度(In-Degree)是指指向该顶点的边的数量。换句话说,它是进入该顶点的边的数量。在有向图中,一个顶点的出度(Out-Degree)是指从该顶点出发的边的数量。换句话说,它是离开该顶点的边的数量。

2、图的存储——邻接矩阵

邻接矩阵的定义如下:

对于无向图G=(V,E),其邻接矩阵是具有下列性质的n阶方阵:

A[i][j]=1,若(vi,vj)是E(G)中的边;

A[i][j]=0,若(vi,vj)不是E(G)中的边。

无向图的邻接矩阵具有对称性,因为边没有方向,即A[i][j]和A[j][i]的值是相同的。

对于有向图,邻接矩阵同样是一个n阶方阵,但不再具有对称性:

A[i][j]=1,若存在一条从vi指向vj的边;

A[i][j]=0,若不存在从vi指向vj的边。

考点一:邻接链表存储

题目:对于下面的有向图,其邻接矩阵是一个7*7的矩阵。采用邻接链表存储时,顶点0的表结点个数为2,顶点3的表结点个数为0,顶点1的表结点个数为2

解析:顶点0的表结点个数为2,顶点3的表结点个数为0,可以看出存储的是出度

八、算法概述

1、算法

算法(Algorithm)是解决问题的一系列明确、有限的步骤或指令的集合。这些步骤或指令通常用于计算、数据处理或自动推理。算法的五个重要特性通常被描述为有穷性、可行性、确定性、输入性和输出性。

有穷性(Finiteness):算法必须在有限步骤内完成。也就是说,算法不能陷入无限循环或需要无限长的时间来执行。

可行性(Feasibility):算法中的每一步都必须是可执行的。这意味着算法中不能有无法实现的操作,比如执行物理上不可能完成的任务或要求超出计算机硬件和软件能力的操作。

确定性(Definiteness):算法中的每一个步骤都必须是明确无误的,不能有任何歧义。也就是说,算法中的指令应该是清晰、无歧义且可以被任何遵循算法的人或机器准确执行的。

输入性(Input):算法通常具有零个或多个输入。这些输入是算法开始执行前所需的信息,它们可能是数据、参数或其他形式的指令。有些算法在没有输入的情况下也能运行(例如,生成随机数或计算数学常数的算法)。

输出性(Output):算法至少有一个输出。输出是算法执行完成后产生的结果。这个结果可能是数据、决策、分类或其他形式的信息。在某些情况下,算法可能仅通过修改其输入或某些全局状态变量来产生输出(而不是直接生成一个可观察的输出)。

2、伪代码

伪代码(Pseudocode)是一种非特定编程语言的方式来描述算法或程序的结构。它使用自然语言结合一些编程的结构(如变量、控制结构、循环等)来描述程序的功能,但不遵循任何特定编程语言的语法规则。

伪代码并没有严格的格式要求,因为其主要目的是清晰地描述算法的逻辑,而不是为了直接执行。然而,为了使伪代码易于理解和阅读,通常会遵循一些常见的编写习惯和约定。

以下是一些建议的伪代码编写习惯和约定:

使用简单的语句:使用自然语言描述算法的主要步骤,避免使用复杂的语句结构。

定义变量:在算法开始时定义所有使用的变量,并给出它们的初始值(如果有的话)。

使用控制结构:使用if、else、for、while等控制结构来描述算法中的条件判断和循环。

注释和说明:在算法的关键部分添加注释和说明,解释算法的工作原理或特定步骤的目的。

缩进和分隔:使用缩进或空行来分隔算法的不同部分,提高可读性。

函数和过程:如果算法包含多个独立的部分,可以使用“函数”或“过程”来组织这些部分,并在调用时给出参数和返回值。

避免具体语法:虽然伪代码可以借鉴编程语言的语法,但应避免使用特定编程语言的特定语法或函数。

使用标准数学符号:在描述数学运算或逻辑运算时,使用标准的数学符号,如 +、-、*、/、=、>、< 等。

九、排序算法的总结

1、时间复杂度

时间复杂度是计算机科学中用来描述算法执行时间随输入规模增长而增长的量度的概念。它反映了算法在解决问题时所耗费的时间资源,也可以理解为算法的运行效率。记作T(n)=O(f(n)),其中T(n)表示算法执行时间,f(n)是算法执行时间与输入规模n的某种函数关系。

如果 T(n) = 3n^2 + 4n + 1,那么大O表示法下它的时间复杂度是 O(n^2)。

如果 T(n) = 2^n,那么大O表示法下它的时间复杂度是 O(2^n)。

如果 T(n) = 100(一个常数),那么大O表示法下它的时间复杂度是 O(1)。

2、时间复杂度的大小

以下是一个常见的时间复杂度大小排序(从低到高):

O(1):常数时间复杂度。无论输入数据规模如何变化,算法的执行时间都是固定的。

O(log n):对数时间复杂度。算法执行时间随着输入数据规模的增长而以对数方式增长。这通常出现在使用分治策略或二分查找等算法中。

O(n):线性时间复杂度。算法执行时间随着输入数据规模的增长而线性增长。例如,遍历一个列表或数组。

O(n log n):线性对数时间复杂度。算法执行时间同时受到输入数据规模和其对数的影响。这通常出现在某些排序算法(如归并排序、快速排序的平均情况)和图算法(如Dijkstra算法)中。

O(n^2):平方时间复杂度。算法执行时间随着输入数据规模的平方增长。例如,冒泡排序和插入排序的最坏情况。

O(n^3):立方时间复杂度。算法执行时间随着输入数据规模的立方增长。这通常出现在一些需要嵌套循环的算法中。

O(2^n):指数时间复杂度。算法执行时间随着输入数据规模的指数增长。这种算法通常只适用于非常小的输入数据规模,因为随着数据规模的增长,执行时间将迅速增加。

O(n!):阶乘时间复杂度。算法执行时间随着输入数据规模的阶乘增长。这种算法在实际应用中很少出现,因为即使对于相对较小的输入数据规模,执行时间也会非常长。

3、时间复杂度的记号

以下是几个常用的时间复杂度记号及其解释:

O(大O表示法):表示算法的时间复杂度上界。也就是说,当输入规模n增大时,算法的实际运行时间最多只会按照O中指定的复杂度增长。例如,O(n)表示算法的时间复杂度是线性的,即算法的运行时间随着输入规模n的增大而线性增长。

Ω(大Ω表示法):表示算法的时间复杂度下界。即算法的运行时间至少会按照Ω中指定的复杂度增长。在实际分析中,大Ω表示法相对较少使用,因为人们通常更关注算法的上界,即最坏情况下的性能。

Θ(大Θ表示法):表示算法的时间复杂度既是上界也是下界,即算法的运行时间基本上会按照Θ中指定的复杂度增长。这意味着算法在最好和最坏情况下的性能都是相近的。

4、排序

排序方法

类别

稳定性

时间复杂度

空间复杂度

辅助存储

直接插入

插入排序

稳定

平均情况: O(n^2)

O(1)

少量

最坏情况: O(n^2)

Shell排序

插入排序

不稳定

平均情况: O(n^1.3)

O(1)

少量

最坏情况: O(n^2)

直接选择

选择排序

不稳定

平均情况: O(n^2)

O(1)

少量

最坏情况: O(n^2)

堆排序

选择排序

不稳定

O(nlog_2n)

O(1)

少量

冒泡排序

交换排序

稳定

平均情况: O(n^2)

O(1)

少量

最坏情况: O(n^2)

快速排序

交换排序

不稳定

平均情况: O(nlog_2n)

O(log_2n)

递归栈

最坏情况: O(n^2)

归并排序

分治排序

稳定

O(nlog_2n)

O(nlog_2n)

需要额外数组

基数排序

分配排序

稳定

O(d(r+n))

O(r+n)

需要额外空间

  • 34
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴回答你关于数据结构算法的问题!在Java中,有许多基础数据结构算法可以使用。下面是一些常见的数据结构算法的介绍: 1. 数组(Array):数组是一种线性数据结构,可以存储相同类型的元素。它们在内存中是连续存储的,并且可以通过索引来访问元素。 2. 链表(Linked List):链表是另一种常见的线性数据结构,它由节点组成,每个节点都包含一个数据项和一个指向下一个节点的指针。 3. 栈(Stack):栈是一种后进先出(LIFO)的数据结构。它支持两个基本操作:push(将元素放入栈顶)和pop(从栈顶删除元素)。 4. 队列(Queue):队列是一种先进先出(FIFO)的数据结构。它支持两个基本操作:enqueue(将元素放入队尾)和dequeue(从队头删除元素)。 5. 树(Tree):树是一种非线性数据结构,它由节点和边组成。每个节点可以有零个或多个子节点。常见的树包括二叉树、二叉搜索树和平衡二叉树。 6. 图(Graph):图是由节点和边组成的非线性数据结构。节点表示对象,边表示节点之间的关系。图可以是有向的或无向的。 在Java中,还有一些常见的算法,包括但不限于以下几种: 1. 排序算法:例如冒泡排序、选择排序、插入排序、快速排序和归并排序等。 2. 查找算法:例如线性查找和二分查找等。 3. 图算法:例如广度优先搜索(BFS)和深度优先搜索(DFS)等。 4. 动态规划:一种通过将问题分解成子问题来解决复杂问题的算法。 这只是数据结构算法的一小部分基础知识,希望对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值