第一部分公共基础知识第1章数据结构与算法1.1算法1.算法的基本概念(1)概念:算法是指一系列解决问题的清晰指令。(2)4个基本特征:可行性、确定性、有穷性、拥有足够的情报。(3)两种基本要素:对数据对象的运算和操作、算法的控制结构(运算和操作时间的顺序)。(4)设计的基本方法:列举法、归纳法、递推法、递归法、减半递推技术和回溯法。2.算法的复杂度(1)算法的时间复杂度:执行算法所需要的计算工作量。(2)算法的空间复杂度:执行算法所需的内存空间。1.2数据结构的基本概念数据结构指相互有关联的数据元素的集合,即数据的组织形式。其中逻辑结构反映数据元素之间逻辑关系;存储结构为数据的逻辑结构在计算机存储空间中的存放形式,有顺序存储、链式存储、索引存储和散列存储4种方式。数据结构按各元素之间前后件关系的复杂度可划分为:(1)线性结构:有且只有一个根节点,且每个节点最多有一个直接前驱和一个直接后继的非空数据结构。(2)非线性结构:不满足线性结构的数据结构。1.3线性表及其顺序存储结构1.线性表的基本概念线性结构又称线性表,线性表是最简单也是最常用的一种数据结构。2.线性表的顺序存储结构·元素所占的存储空间必须连续。·元素在存储空凤的位置是按逻辑顺序存放的。3.线性表的插入运算在第i个元素之前插入一个新元素的步骤如下:步骤一:把原来第n个节点至第i个节点依次往后移一个元素位置。步骤二:把新节点放在第i个位置上。步骤三:修正线性表的节点个数。在最坏情况下,即插入元素在第一个位置,线性表中所有元素均需要移动。4.线性表的删除运算删除第i个位置的元素的步骤如下:步骤一:把第i个元素之后不包括第i个元素的n—i个元素依次前移一个位置;步骤二:修正线性表的结点个数。1.4栈和队列1.栈及其基本运算(1)基本概念:栈是一种特殊的线性表,其插入运算与删除运算都只在线性表的一端进行,也被称为“先进后出”表或“后进先出”表。·栈顶:允许插入与删除的一端。·栈底:栈顶的另一端。·空栈:栈中没有元素的栈。(2)特点。·栈顶元素是最后被插入和最早被删除的元素。·栈底元素是最早被插入和最后被删除的元素。·栈有记忆作用。·在顺序存储结构下,栈的插入和删除运算不需移动表中其他数据元素。·栈顶指针top动态反映了栈中元素的变化情况(3)顺序存储和运算:入栈运算、退栈运算和读栈顶运算。2.队列及其基本运算(1)基本概念:队列是指允许在一端进行插入,在另一端进行删除的线性表,又称“先进先出”的线性表。·队尾:允许插入的一端,用尾指针指向队尾元素。·排头:允许删除的一端,用头指针指向头元素的前一位置。(2)循环队列及其运算。所谓循环队列,就是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间。入队运算是指在循环队列的队尾加入一个新元素。当循环队列非空(s=1)且队尾指针等于队头指针时,说明循环队列已满,不能进行入队运算,这种情况称为“上溢”。退队运算是指在循环队列的队头位置退出一个元素并赋给指定的变量。首先将队头指针进一,然后将排头指针指向的元素赋给指定的变量。当循环队列为空(s=O)时,不能进行退队运算,这种情况称为T溢”。1.5线性链表在定义的链表中,若只含有一个指针域来存放下一个元素地址,称这样的链表为单链表或线性链表。在链式存储方式中,要求每个结点由两部分组成:一部分用于存放数据元素值,称为数据域;另一部分用于存放指针,称为指针域。其中指针用于指向该结点的前一个或后一个结点(即前件或后件)。1.6树和二叉树1.树的基本概念树是简单的非线性结构,树中有且仅有一个没有前驱的节点称为“根”,其余节点分成m互不相交的有限集合Tl,T2,…,T。,每个集合又是一棵树,称Tl,rI2,…,T。为根结点的子树。·父节点:每一个节点只有一个前件,无前件的节点只有一个,称为树的根结点(简称树的根)。·子节点:每一个节点可以后多个后件,无后件的节点称为叶子节点。·树的度:所有节点最大的度。·树的深度:树的最大层次。2.二叉树的定义及其基本性质(1)二叉树的定义:二叉树是一种非线性结构,是有限的节点集合,该集合为空(空二叉树)或由一个根节点及两棵互不相交的左右二叉子树组成。可分为满二叉树和完全二叉树,其中满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。二叉树具有如下两个特点:·二叉树可为空,空的二叉树无节点,非空二叉树有且只有一个根结点;·每个节点最多可有两棵子树,称为左子树和右子树。(2)二叉树的基本性质。性质1:在二叉树的第k层上至多有2k-1个结点(k≥1)。性质2:深度为m的二叉树至多有2m-1个结点。性质3:对任何一棵二叉树,度为0的结点(即叶子结点)总是比度为2的结点多一个。性质4:具有n个结点的完全二叉树的深度至少为[lOg2n]+1,其中[Log2n]表示lOg2n的整数部分。3.满二叉树与完全二叉树(1)满二叉树:满二叉树是指这样的一种二叉树:除最后一层外,每一层上的所有结点都有两个子结点。满二叉树在其第i层上有2i-1个结点。从上面满二叉树定义可知,二叉树的每一层上的结点数必须都达到最大,否则就不是满二叉树。深度为m的满二叉树有2m-1个结点。(2)完全二叉树:完全二叉树是指这样的二叉树:除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的满二叉树中编号为1—n的结点一一对应。4.二叉树的存储结构二叉树通常采用链式存储结构,存储节点由数据域和指针域(左指针域和右指针域)组成。二叉树的链式存储结构也称二叉链表,对满二叉树和完全二叉树可按层次进行顺序存储。5.二叉树的遍历二叉树的遍历是指不重复地访问二叉树中所有节点,主要指非空二叉树,对于空二叉树则结束返回。二叉树的遍历包括前序遍历、中序遍历和后序遍历。(1)前序遍历。前序遍历是指在访问根结点、遍历左子树与遍历右子树这三者中,首先访问根结点,然后遍历左子树,最后遍历右子树;并且,在遍历左右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。前序遍历描述为:若二叉树为空,则执行空操作;否则①访问根结点;②前序遍历左子树;③前序遍历右子树。(2)中序遍历。中序遍历是指在访问根结点、遍历左子树与遍历右子树这三者中,首先遍历左予树,然后访问根结点,最后遍历右子树;并且,在遍历左、右子树时,仍然先遍历左子树,然后访问根结点,最后遍历右子树。中序遍历描述为:若二叉树为空,则执行空操作;否则①中序遍历左子树;②访问根结点;③中序遍历右子树。(3)后序遍历。后序遍历是指在访问根结点、遍历左子树与遍历右子树这三者中,首先遍历左子树,然后遍历右子树,最后访问根结点,并且,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后访问根结点。后序遍历描述为:若二叉树为空,则执行空操作;否则①后序遍历左子树;②后序遍历右子树;③访问根结点。1.7查找技术(1)顺序查找:在线性表中查找指定的元素。最坏情况下,最后一个元素才是要找的元素,则需要与线性表中所有元素比较,比较次数为n。(2)二分查找:二分查找也称折半查找,它是一种高效率的查找方法。但二分查找有条件限制,它要求表必须用顺序存储结构,且表中元素必须按关键字有序(升序或降序均可)排列。对长度为n的有序线性表,在最坏情况下,二分查找法只需比较lOg2n次。1.8排序技术(1)交换类排序法。·冒泡排序:通过对待排序序列从后向前或从前向后,依次比较相邻元素的排序码,若发现逆序则交换,使较大的元素逐渐从前部移向后部或较小的元素逐渐从后部移向前部,直到所有元素有序为止。在最坏情况下,对长度为n的线性表排序,冒泡排序需要比较的次数为n(n-1)/2。·快速排序:是迄今为止所有内排序算法中速度最快的一种。它的基本思想是:任取待排序序列中的某个元素作为基准(一般取第一个元素),通过一趟排序,将待排元素分为左右两个子序列,左子序列元素的排序码均小于或等于基准元素的排序码,右子序列的排序码则大于基准元素的排序码,然后分别对两个子序列继续进行排序,直至整个序列有序。最坏情况下,即每次划分,只得到一个序列,时间效率为0(n2)。(2)插入类排序法。·简单插入排序法:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-l个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。在最坏情况下,即初始排序序列是逆序的情况下,比较次数为n(n-1)/2,移动次数为n(n-1)/2。·希尔排序法:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。(3)选择类排序法。·简单选择排序法:扫描整个线性表,从中选出最小的元素,将它交换到表的最前面;然后对剩下的子表采用同样的方法,直到子表空为止。最坏情况下需要比较n(n-1)/2次。·堆排序的方法:首先将一个无序序列建成堆;然后将堆顶元素(序列中的最大项)与堆中最后一个元素交换(最大项应该在序列的最后)。不考虑已经换到最后的那个元素,只考虑前n-l个元素构成的子序列,将该子序列调整为堆。反复做步骤②,直到剩下的子序列空为止。在最坏情况下,堆排序法需要比较的次数为0(nlOg2n)。相关真考题库试题(1)下列叙述中正确的是(D)A)一个算法的空间复杂度大,则其时间复杂度也必定大B)一个算法的空间复杂度大,则其时间复杂度必定小c)一个算法的时间复杂度大,则其空间复杂度必定小D)算法的时间复杂度与空间复杂度没有直接关系【解析】算法的空间复杂度是指算法在执行过程中所需要的内存空间,算法的时间复杂度,是指执行算法所需要的计算工作量,两者之间并没有直接关系,答案为D。(2)下列叙述中正确的是(B)A)算法的效率只与问题的规模有关,而与数据的存储结构无关B)算法的时间复杂度是指执行算法所需要的计算工作量C)数据的逻辑结构与存储结构是一一对应的D)算法的时间复杂度与空间复杂度一定相关【解析】算法的效率与问题的规模和数据的存储结构都有关,A错误。算法的时间复杂度,是指执行算法所需要的计算工作量,B正确。由于数据元素在计算机存储空间中的位置关系可能与逻辑关系不同,因此数据的逻辑结构和存储结构不是一一对应的,C错误。算法的时间复杂度和空间复杂度没有直接的联系,D错误。(3)下列叙述中正确的是(A)A)程序执行的效率与数据的存储结构密切相关B)程序执行的效率只取决于程序的控制结构~c)程序执行的效率只取决于所处理的数据量D)以上说法均错误【解析】程序执行的效率与数据的存储结构、数据的逻辑结构、程序的控制结构、所处理的数据量等有关。(4)下列关于栈的叙述中,正确的是(C)A)栈底元素一定是最后入栈的元素B)栈顶元素一定是最先人栈的元素c)栈操作遵循先进后出的原则D)以上说法均错误【解析】栈顶元素总是后被插入的元素,从而也是最先被删除的元素;栈底元素总是最先被插入的元素,从而也是最后才能被删除的元素。栈的修改是按后进先出的原则进行的。因此,栈称为先进后出表,或“后进先出”表,所以选择C。(5)-个栈的初始状态为空。觋将元素l,2,3,A,B,C依次入栈,然后再依次出栈,则元素出栈的顺序是(C)A)1,2,3,A,B,CB)C,B,A,1,2,3C)C,B,A,3,2,1D)1,2,3,C,B,A【解析】栈的修改是按后进先出的原则进行的,所以顺序应写入栈顺序相反,故选C。(6)下列与队列结构有关联的是(D)A)函数的递归调用B)数组元素的引用c)多重循环的执行D)先到先服务的作业调度【解析】队列的修改是依先进先出的原则进行的,D正确。(7)下列叙述中正确的是(A)A)循环队列中的元素个数随队头指针与队尾指针的变化而动态变化B)循环队列中的元素个数随队头指针的变化而动态变化c)循环队列中的元素个数随队尾指针的变化而动态变化D)以上说法