一、单项选择题
1. 某算法的空间复杂度为O(1),则____。
A.该算法执行不需要任何辅助空间
B.该算法执行所需辅助空间大小与问题规模n无关
C.该算法执行不需要任何空间
D.该算法执行所需全部空间大小与问题规模n无关
2. 在长度为n的顺序表中插入一个元素,对应算法的时间复杂度为____。
A.
O
(
1
)
O(1)
O(1)
B.
O
(
l
o
g
2
n
)
O(log_2^n)
O(log2n)
C.
O
(
n
)
O(n)
O(n)
D.
O
(
n
2
)
O(n^2)
O(n2)
3. 设线性表中有n个元素,以下运算中,____在单链表上实现要比在顺序表上实现效率更高。
A.删除指定位置元素的后一个元素
B.在最后一个元素的后面插入一个新元素
C.顺序输出前k个元素
D.交换第i个元素和第n-i+1个元素的值(i=1,2,…,n)
4. 以下数据结构中元素之间为非线性关系的是____。
A.栈
B.队列
C.线性表
D.以上都不是
5. 若一个栈用数组data[1…n]存储,初始栈顶指针top为n+1,则以下元素x进栈的正确操作是____。
A.top++;data[top]=x;
B.data[top]=x;top++;
C.top–;data[top]=x;
D.data[top]=x;top–;
6. 若某循环队列有队首指针front和队尾指针rear,在队不满时进队操作仅会改变____。
A.front
B.rear
C.front和rear
D.以上都不队
=7. 设循环队列中数组的下标是0~N-1,其队头、队尾指针分别为f和r(f指向队首元素的前一位置,r指向队尾元素),则其元素个数为____。
A.r-f
B.r-f-1
C.(r-f)%N+1
D.(r-f+N)%N
8. 现要设计一个高效的算法,在一个长度为n的有序顺序表中删除所有元素值为x的元素(假设这样的元素是不唯一的),这样的算法时间复杂度为____。
A.
O
(
n
)
O(n)
O(n)
B.
O
(
n
l
o
g
2
n
)
O(nlog_2^n)
O(nlog2n)
C.
O
(
n
2
)
O(n^2)
O(n2)
D.
O
(
n
)
O(\sqrt n)
O(n)
9. 在一个带头结点的循环双链表L中,要删除p所指结点,算法的时间复杂度为____。
A.
O
(
n
)
O(n)
O(n)
B.
O
(
n
)
O(\sqrt n)
O(n)
C.
O
(
1
)
O(1)
O(1)
D.
O
(
n
2
)
O(n^2)
O(n2)
10. 设树T的度为4,其中度为1、2、3、4的结点个数分别为4、2、1、1,则T中的叶子结点个数是____。
A.5
B.6
C.7
D.8
11. 设森林F中有4棵树,第1、2、3、4棵树的结点个数分别为a、b、c、d,将森林F转换为一颗二叉树B,则二叉树B根结点的左子树上的结点个数是____。
A.a-1
B.a
C. a+b+c (二叉树B根结点的右子树上的结点个数)
D.b+c+d
12. 下列关于图的叙述中,正确的是____。
Ⅰ.回路是简单路径
Ⅱ.存储稀疏图,用邻接矩阵比邻接表更省空间 (存储稀疏图用零阶矩阵更节省空间)
Ⅲ.若有向图中存在拓扑序列,则该图不存在回路
A. 仅Ⅱ
B. 仅Ⅰ、Ⅱ
C. 仅Ⅲ
D. 仅Ⅰ、Ⅲ
13. 以下关于有向图的说法中,正确的是____。
A.强连通图是任何顶点到其他所有顶点都有边
B.完全有向图一定是强连通图
C.有向图中任一顶点的入度等于出度
D.有向图边集的子集和顶点集的子集可构成原有向图的子图
14. 如果从无向图的任一顶点出发进行一次广度优先遍历即可访问所有顶点,则该图一定是____。
A.完全图
B.连通图
C.有回路
D.一棵树
15. 用Dijkstra算法求一个带权有向图G中从顶点0出发的最短路径,在算法执行的某时刻,S={0,2,3,4},下一步选取的目标顶点可能是____。
A.顶点2
B.顶点3
C.顶点4
D.顶点7
16. 哈希表中出现冲突是指____。
A. 两个元素具有相同的序号
B. 两个元素的关键字不同,而其他属性相同
C. 数据元素过多
D. 两个元素的关键字不同,而对应的哈希函数值(存储地址)相同
17. 适合于折半查找的数据组织方式是____。
A.以链表存储的线性表
B.以顺序表存储的任意线性表
C.以链表存储的有序线性表
D.以顺序表存储的有序线性表
18. 对有n个记录的表进行直接插入排序,在最好情况下需比较____次关键字。
A.n-1
B.n+1
C.n/2
D.n(n-1)/2
19. 若数据元素序列{11,12,15,7,8,9,23,1,5}是采用下列排序方法之一得到的第二趟排序后的结果,则该排序算法只能是____。
A.冒泡排序
B.直接插入排序
C.选择排序
D.二路归并排序
20. 对一组数据(25,84,21,47,15,27,68,35,20)进行排序,前3趟的排序结果如下:
第1趟:20,15,21,25,47,27,68,35,84
第2趟:15,20,21,25,35,27,47,68,84
第3趟:15,20,21,25,27,35,47,68,84
则所采用的排序方法是____。
A.简单选择排序
B.希尔排序
C.二路归并排序
D.快速排序
二、问答题
1. 对于如图1所示的带权无向图,直接给出利用普里姆算法(从顶点0开始构造)和克鲁斯卡尔算法构造出的最小生成树的结果。
- 利用普里姆算法从顶点0出发构造的最小生成树为:{(0,1),(0,3),(1,2),(2,5),(5,4)}。
利用克鲁斯卡尔算法构造出的最小生成树为:{(0,1),(0,3),(1,2),(5,4),(2,5)} 。
2. 假设一棵二叉排序树的关键字为单个字母,其后序遍历序列为ACDBFIJHGE,回答以下问题:
(1)画出该二叉排序树。
(2)求在等概率下的查找成功的平均查找长度。
(3)求在等概率下的查找不成功的平均查找长度。
- A S L 成功 = 1 × 1 + 2 × 2 + 3 × 4 + 4 × 2 + 5 × 1 10 = 3 ASL_{成功}=\frac{1×1+2×2+3×4+4×2+5×1}{10}=3 ASL成功=101×1+2×2+3×4+4×2+5×1=3
- A S L 失败 = 3 × 6 + 4 × 3 + 5 × 2 11 = 40 11 ASL_{失败}=\frac{3×6+4×3+5×2}{11}=\frac{40}{11} ASL失败=113×6+4×3+5×2=1140
3. 已知序列{15,5,16,2,25,8,20,9,18,12},给出采用二路归并排序法对该序列作升序排序时的每一趟的结果。
- 第一趟:5 15 2 16 8 25 9 20 12 18
- 第二趟:2 5 15 16 8 9 20 25 12 18
- 第三趟:2 5 8 9 15 16 20 25 12 18
- 第四趟:2 5 8 9 12 15 16 18 20 25
4. 简要回答下列关于堆排序中堆的一些问题:
(1)通常堆采用顺序还是链式存储结构?
(2)设有一个小根堆,即堆中任意结点的关键字均小于它的左孩子和右孩子的关键字。其中具有最大关键字的结点可能在什么地方?
- 通常堆采用顺序存储结构,可以方便找到其孩子结点以及父结点。
- 小根堆中具有最大关键字的结点只可能出现在叶子结点中。因为最小堆的最小关键字的结点必是根结点,而最大关键字的结点由偏序关系可知,只有叶子结点可能是最大关键字的结点。
5. 对于图1所示的带权有向图,采用Dijkstra算法求从顶点0到其他顶点的最短路径,要求给出求解过程,包括每一步的S集合、dist和path数组元素。
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
visited[5] | √ | ② | ③ | ④ | ① |
dist[5] | 0 | 5 | 6 | 7 | 2 |
path[5] | -1 | 4 | 1 | 1 | 0 |
- 0 − 1 ( 6 ) 0 − 4 − 1 − 2 ( 6 ) 0-1(6)\;\;\;\;\;0-4-1-2(6) 0−1(6)0−4−1−2(6)
- 0 − 4 − 1 − 3 ( 7 ) 0 − 4 ( 2 ) 0-4-1-3(7)\;\;\;\;\;0-4(2) 0−4−1−3(7)0−4(2)
三、算法设计题
1. 某带头结点的非空单链表L中所有元素为整数,结点类型定义如下:
typedef struct node
{ int data;
struct node *next;
} LinkNode;
设计一个尽可能高效的算法,将所有小于零的结点移到所有大于等于零的结点的前面。
- 算法思想:先将单链表的头结点和首结点摘下,将首结点的指针域置为NULL。将小于等于零的结点采用头插法,大于零的结点采用尾插法。
void Sort(LinkNode *L)
{
LinkNode* r=L->next,*p=L->next->next,*q;
L->next->next = NULL;
while (p != NULL)
{
if (p->data < 0)
{
q = p->next;
p->next = L->next;
L->next = p;
p = q;
}
else
{
q = p->next;
p->next = r->next;
r->next = p;
r = r->next;
p = q;
}
}
}
运行结果
- 程序分析:
时间复杂度:O(n);空间复杂度:O(1)
2. 假设二叉树中有n个结点,每个结点值为单个字符,而且所有结点值均不相同,采用二叉链存储结构存储,其结点类型定义如下:
typedef struct node
{ char data;
struct node *lchild,*rchild;
} BTNode;
请完成以下任务:
(1)设计一个算法,在二叉树b中查找x结点(指结点值为x的结点),若找到该结点,返回其地址,否则返回NULL。给出你设计的算法的时间复杂度。
(2)设计一个算法,利用(1)小题设计的算法输出二叉树b中x结点的所有子孙结点值。
第(1)问:
BiTNode* Findx(BiTNode* b, ElemType x) //在二叉树b中查找x结点
{
BiTNode* p;
if (b == NULL) return NULL; //空树
else
{
if (b->data == x) return b;
p = Findx(b->lchild, x); //左子树中查找
if (p != NULL) return p;
return Findx(b->rchild, x); //右子树中查找
}
}
- 算法的时间复杂度为O(n)
第(2)问:
void Sons(BiTNode* b, ElemType x)//输出x结点的子孙,初始时b指向x结点
{
if (b != NULL)
{
if (b->data != x) printf("%c ", b->data); //输出子孙结点
Sons(b->lchild, x); //递归输出左子树中的子孙
Sons(b->rchild, x); //递归输出右子树中的子孙
}
}
void OutSons(BiTNode* b, ElemType x)//输出二叉树b中x结点的所有子孙结点值
{
BiTNode* p = Findx(b, x); //查找结点值为x的地址
if (p != NULL) Sons(p, x); //此结点若存在,则输出其子孙结点
}