习题总结003

时间:2024-05-20 20:37:54

1. 下列有关图的遍历说法中,不正确的是( C )

A.有向图和无向图都可以进行遍历操作

B.基本遍历算法两种:深度遍历和广度遍历

C.图的遍历必须用递归实现

D.图的遍历算法可以执行在有回路的图中

解析:其实所有的递归都可以变成非递归,通过使用栈来实现。因为栈可以模拟递归的过程,最开始的操作和状态压到栈,然后紧接的递归调用一个一个地压进去,然后遇到return就返回,相当于是从堆栈弹出出来,一个一个地return出来,就是一个个地弹出来。

 

2. 具有 n 个整数的数组 A=[29,6,28,20,2,24] 使用插入排序( Insertion Sort )算法排序,算法伪代码如下:

习题总结003经过三趟排序后,数组 A 的排列状态将是( C )

A.6,29,28,20,2,24

B.6,28,20,2,24,29

C.6,20,28,29,2,24

D.2,6,20,24,28,29

解析:

实现机理是这样的:

有一组数据A=[29,6,28,20,2,24]

①第一次先排前俩,第二次排前三。。。。以此类推

②先获取A[j]的值存入一个变量中

③每次循环判断大小的目的就是为了找到A[j-1]小于e的情况

④当出现前大于e的情况,那就把大的值后移,也就是赋值给A[j]

⑤当出现前不大于e的时候(A[j-i]<e),break跳出,此时j不减减,此时j的位置就是需要e来填充的

第一趟的结果为6 29 28 20 2 24

第二趟为6 28 29 20 2 24

第三趟:  j为3,e为A[3] = 20,那么先比较的就是A[3-1]和e,其结果为A[3]被赋值为A[3-1],

而后j-- 进入A[2-1]和e的判断,同样是A[2]被赋值为A[1],

然后再判断A[0]和e,发现A[0]小于e,break退出,此时j=1,A[1]=e;end;

所以三轮结束后,结果应该是:6,20,28,29,2,24

 

3. 当采用分快查找时,数据的组织方式为 (  B  )

A.数据分成若干块,每块内数据有序

B.数据分成若干块,每块内数据不必有序,但块间必须有序,每块内最大(或最小)的数据组成索引块

C.数据分成若干块,每块内数据有序,每块内最大(或最小)的数据组成索引块

D.数据分成若干块,每块(除最后一块外)中数据个数需相同

解析:

分块查找法要求将列表组织成以下索引顺序结构:

首先将列表分成若干个块(子表)。一般情况下,块的长度均匀,最后一块可以不满。

每块中元素任意排列,即块内无序,但块与块之间有序。

构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,和每块中最大

关键字(或最小关键字)。索引表按关键字有序排列。

 

4. 希望用最快的速度从一个无序数组中挑选出其中前十个最大的元素,在以下的排序方法中( B )

A.快速排序

B.堆排序

C.归并排序

D.基数排序

解析:用堆排序最好,因为堆排序不需要等整个排序结束就可挑出前50个最大元素,而快速排序和基数排序都需等待整个排序结束才能知道前50个最大元素。

 

5. 用二分法查找长度为10的、排好序的线性表,查找不成功时,最多需要比较多少次?( B )

A.3           B.4           C.5           D.6

解析:二分查找,可以用二叉判定树,查找不成功的次数不超过判定树的深度,即(log2n)+1,其中log2n向下取整

二分查找类似于二叉树每层顶点的个数,2**3 =8 2**4 = 16 显然 8 <10 <16,取上整,所以等于4

 

6.对两个数组 a 和 b 进行如下初始化

习题总结003

以下叙述正确的是(  D   )

A.a 与 b 数组完全相同

B.a 与 b 长度相同

C.a 和 b 中都存放了字符串

D.a 数组比 b 数组长

解析:题目说的是长度,应该是strlen(),对a求长度为6,但是对b求长度是一个未知的大小,应该strlen()知道遇到'\0'才停止,所以a,b之间的长度不能比较,sizeof是大小,sizeof(a)=7,sizeof(b)=6,应该把题目的长度换成大小

 

7.下列给定程序中,函数fun的功能是:把形参a所指数组中的奇数按原顺序依次存放到a[0]、a[1]、a[2]…中,把偶数从数组中删除,奇数个数通过函数值返回。 例如,若a所指数组中的数据最初排列为:9,1,4,2,3,6,5,8,7,删除偶数后,a所指数组中的数据为:9,1,3,5,7,返回值为5。
请在程序的下画线处填入正确的内容并将下画线删除,使程序得出正确的结果。( D )
试题程序:

习题总结003

A.0   j++   j

B.1   j++   j+1

C.0   j++   j+1

D.1   j++   j

解析:int fun (int a[], int n)
{
    int i, j;
    j=0;
    for (i=0; i<n; i++)
    /**********found**********/
    if (a[i]%2== 1 ) // 这里是要判断为奇数时,将其值存储到新的位置
    {
        /**********found**********/
        a[j]=a[i];
        j++; // j为新索引,每次赋值后需要加1
    }
    /**********found**********/
    return j; // 因为在上一步中已经加过1了,所以这里直接返回j即可
}
结果如下:
The original data:
   9   1   4   2   3   6   5   8   7
The number of odd: 5
The odd number:
   9   1   3   5   7
 

 

8.以下多维数组声明语句中,不正确的有( B )。

A.int[,]a = new int[2,3];

B.int[,] a = {{1,2,3}};

C.int[2,3] a = new int[2,3];

D.int[,] a = {{1,2,3},{2,3}}

解析:二维数组,你要么左侧中括号中显示行数列数,要么右侧大括号中显示出。选项b 列数不明确

 

9.给定一个整数sum,从有N个有序元素的数组中寻找元素a,b,使得a+b的结果最接近sum,最快的平均时间复杂度是:( A )

A.O(n)

B.O(nlogn)

C.O(n^2)

D.O(logn)

解析:

思想类似于两端向中间扫描

1、设定两个指针P1、P2,分别指向数组开始和结尾,即P1指向最小值,P2指向最大值;

2、计算 *P1+*P2 的值为 SUM,与 sum 比较,记录它们的差值 DIF 和 SUM,若 SUM<sum,P1++,若SUM>sum,P2--;

3、重复以上过程直到DIF最小

 

10.以下操作中,数组比链表速度更快的是(ACE)

A.原地逆序

B.头部插入

C.返回中间节点

D.返回头部节点

E.选择随机节点

解析:

A选项,如果是数组只要遍历一半元素就可以了,翻转的思想类似于字符串逆序,但链表如果要完成逆序,就算只是修改指针也要把所有的元素遍历完,所以相比而言数组还是比链表快的。

B链表只需插入一个节点,数组需移动n个元素

C选项的访问中间节点,数组可以通过array[length/2]访问,链表需要依次查找到中间节点。

D头结点都一样

E 数组是顺序存储的线性表,相对于链表而言主要的优点就是可以通过下标随机访问数组中的任意元素。