单项选择(2016年春程序员软考)

对于n个元素的关键码序列{k1,k2,…,kn},当且仅当满足下列关系时称其为堆。

以下关键码序列中,【 】不是堆。

A、12,25,22,53,65,60,30

B、12,25,22,30,65,60,53

C、65,60,25,22,12,53,30

D、65,60,25,30,53,12,22

答案解析

C

讨论

对n个记录进行非递减排序,在第一趟排序之后,一定能把关键码序列中的最大或最小元素放在其最终排序位置上的排序算法是【 】。

设有二叉排序树如下图所示,根据关键码序列【 】可构造出该二叉排序树。

某图G的邻接矩阵如下所示。以下关于该图的叙述中,错误的是【 】

对于关键码序列(54,34,5,14,50,36,47,83),用链地址法(或拉链法)解决冲突构造散列表(即将冲突的元素存储在同一个单链表中,单链表的头指针存入散列地址对应的单元),设散列函数为H(Key)= Key MOD7(MOD表示整除取余运算),则构造散列冲突次数最多的哈希单元的地址是【 】。

某二又树的先序遍历序列为 ABCDFGE,中序遍历序列为 BAFDGCE。以下关于该二又树的叙述中,正确的是【 】。

对二叉树中的结点如下编号:树根结点编号为1,根的左孩子结点编号为2、右孩子结点编号为3,以此类推,对于编号为i的结点,其左孩子编号为2i、右孩子编号为2i+1。例如,下图所示二又树中有6个结点,结点a、b、c、d、e、f的编号分别为1、2、3、5、7、11。那么,当结点数为n(n>0)的【 】时,其最后一个结点编号为2n-1。

队列采用如下图所示的循环单链表表示,左图表示队列为空,右图为e1、e2、e3依次入队列后的状态,其中,rear指针指向队尾元素所在结点,size为队列长度。以下叙述中,正确的是【 】。

设有初始为空的栈S,对于入栈序列a、b、c、d,经由一个合法的进栈和出栈操作序列后(每个元素进栈、出栈各1次),以c作为第一个出栈的元素时,不能得到的序列为【 】。

对于长度为n的线性表(即n个元素构成的序列),若采用顺序存储结构(数组存储),则在等概率下,删除一个元素平均需要移动的元素数为【 】。

递归函数执行时,其调用和返回控制是利用【 】来进行的。

搜索引擎会通过日志文件把用户每次检索使用的所有查询串都记录下来,每个查询串的长度不超过255 字节。假设目前有一千万个查询记录(重复度比较高,其实互异的查询串不超过三百万个;显然,一个查询串的重复度越高,说明查询它的用户越多,也就是越热门)。现要统计最热门的 10 个查询串,且要求使用的内存不能超过 1GB。以下各方法中,可行且效率最高的方法是【 】。

与算术表达式3-(2+7)/4对应的二又树为【 】。

某二叉排序树如下所示,新的元素45应作为【 】插入该二叉树中。

设有字符串S='software',其长度为3的子串数目为【 】。

对于下图,从顶点1进行深度优先遍历时,不可能得到的遍历序列是【 】

函数 Reverselist(LinkList headptr)的功能是将含有头结点的单链表就地逆置。处理思路是将链表中的指针逆转,即将原链表看成由两部分组成,已经完成逆置的部分和未完成逆置的部分,令s指向未逆置部分的第一个结点,并将该结点插入已完成部分的表头(头结点之后),直到全部结点的指针域都修改完成为止。例如,某单链表如图所示,逆置过程中指针s的变化情况如图(a)(b)所示。链表结点类型定义如下:typedef struct Node{ int data, struct Node *next;}Node, *LinkList;void ReverseList (LinkList headptr){//含头结点的单链表就地逆置, headptr为头指针 LinkList p,s; if(__(1)__) return;//空链表(仅有头结点)时无需处理 p=__(2)__;//令p指向第一个元素结点 if (!p->next) return;//链表中仅有一个元素结点时无需处理 s= p->next;//s指向第二个元素结点 __(3)__=NULL;//设置第一个元素结点的指针域为空 while (s){ p=s;//令p指向未处理链表的第一个结点 s=__(4)__; p-> next= headptr-> next;//将p所指结点插入已完成部分的表头 headptr-> next=__(5)__; }}

设有字符串S= "software",其长度为3的子串数目为【 】。

阅读以下说明和C函数,填补函数代码中的空缺(1)~(5)。队列是一种常用的数据结构,其特点是先入先出,即元素的插入在表头、删除在表尾进行。下面采用顺序存储方式实现队列,即利用一组地址连续的存储单元存放队列元素,同时通过模运算将存储空间看作一个环状结构(称为循环队列)。设循环队列的存储空间容量为 MAXQSIZE,并在其类型定义中设置base、rear和 length三个域变量,其中,base为队列空间的首地址,rear为队尾元素的指针, length表示队列的长度。#define MAXQSIZE 100typedef struct{ QElemType *base;/*循环队列的存储空间首地址* int real;/*队尾元素索引*/ int ength;/*队列的长度*/} SqQueue;例如,容量为8的循环队列如下图所示,初始时创建的空队列如图(a)所示,经过一系列的入队、出队操作后,队列的状态如图(b)所示(队列长度为3)。 下面的C函数1、C函数2和C函数3用于实现队列的创建、插入和删除操作,请完善这些代码。【C函数1】创建一个空的循环队列int InitQueue (SqQueue *Q){ /*创建容量为 MAXQSIZE的空队列,若成功则返回1;否则返回0*/ Q->base =(QElemType *)malloc( MAXQSIZE*__ (1)__); if (! Q->base) return 0: Q->length=0; Q->rear =0; return 1;}/* InitQueue*/【C函数2】元素插入循环队列。int EnQueue( SqQueue *Q, QElemType e){/*元素e入队,若成功则返回1;否则返回0*/ if( Q->length>=MAXQSIZE) return 0; Q->rear=__(2)__; Q->base [Q->rear]=e; __(3)__; return 1;}/*EnQueue*/【C函数3】元素出循环队列。int DeQueue (SqQueue *Q,QElemType *e){ /*若队列不空,则删除队头元素,由参数e带回其值并返回1;否则返回0*/ if(__(4)__)return 0; *e=Q-base[(Q->rear-Q->length+1+MAXQSIZE)%MAXQSIZE]; __(5)__; return 1;}/*DeQueue*/

阅读以下说明和C函数,填补代码中的空缺(1)~(6)。二叉树的宽度定义为含有结点数最多的那一层上的结点数。函数 GetWidth()用于求二叉树的宽度。其思路是根据树的高度设置一个数组 counter[], counter[i]存放第i层上的结点数,并按照层次顺序来遍历二又树中的结点,在此过程中可获得每个结点的层次值,最后从counter[]中取出最大的元素就是树的宽度。按照层次顺序遍历二叉树的实现方法是借助一个队列,按访问结点的先后顺序来记录结点,离根结点越近的结点越先进入队列,具体处理过程为:先令根结点及其层次号(为1)进入初始为空的队列,然后在队列非空的情况下,取出队头所指示的结点及其层次号,然后将该结点的左子树根结点及层次号入队列(若左子树存在),其次将该结点的右子树根结点及层次号入队列(若右子树存在),然后再取队头,重复该过程直至完成遍历。设二叉树采用二叉链表存储,结点类型定义如下:typedef struct BTNode{ TElemType data; struct BTNode *left, *right;}BTNode, *BiTree;队列元素的类型定义如下:typedef struct{ BTNode *ptr; int LevelNumber;}QElemType;Get Width()函数中用到的函数原型如下所述,队列的类型名为 QUEUE:InitQueue(QUEUE *Q):初始化一个空队列,成功时返回值为1,否则返回值0isEmpty(QUEUE Q):判断队列是否为空,是空则为1,否则为0EnQueue( QUEUE*Q, QElemType a):将元素a加入队列,成功返回值为1,否则返回值0DeQueue(QUEUE *Q, QElemType *):删除队头元素,并通过参数带回其值,成功则返回值1,否则返回值0GetHeight (BiTree root):返回值为二叉树的高度(即层次数,空二叉树的高度为0)int Getwidth(BiTree root){ QUEUE Q; QElemType a, b; int width,height= GetHeight(root); int i, *counter =(int *)calloc(height+1, sizeof (int)); if(__(1)__) return -1;/*申请空间失败*/ if(! root) return 0;/*空树的宽度为0*/ if(__(2)__) return -1;/*初始化队列失败时返回*/ a.ptr= root; a.LevelNumber=1; if(! EnQueue(&Q,a)) return -1;/*元素入队列操作失败时返回*/ while (! isEmpty(Q)){ if(__(3)__)return -1;/*出队列操作失败时返回*/ counter[b. LevelNumber]++;/*对层号为b. LevelNumber的结点计数*/ if(b.ptr->left){/*若左子树存在,则左子树根结点及其层次号入队*/ a.ptr= b.ptr->left; a.LevelNumber=__(4)__; if(!EnQueue(&Q,a)) return -1; } if(b.ptr-> right){/*若右子树存在,则右子树根结点及其层次号入队*/ a.ptr= b.ptr->right; a. LevelNumber=__(5)__; if(! EnQueue(&Q,a)) return -1; } } width= counter[1]; for(i=1; i< height +1; 1++)/*求 counter[]中的最大值*/ if(__(6)__)width= counter [i]; free(counter); return width;}

在解决计算机与打印机之间速度不匹配的问题时,通常设置一个打印数据缓冲区,计算机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区取出数据。因此,该缓冲区的数据结构应该是【 】。