山东科技大学2021数据结构期末考试题目

我们学校今年的考试是判断十个,选择十五个,以及两个函数和一个编程题,另外实验一块考的,实验是一个函数,一个编程。

R1-1

将N个数据按照从小到大顺序组织存放在一个单向链表中。如果采用二分查找,那么查找的平均时间复杂度是O(logN)。(2分)

F

R1-2

对于带权无向图 G = (V, E),M 是 G 的最小生成树,则 M 中任意两点 V1 到 V2 的路径一定是它们之间的最短路径。(2分)

F

R1-3

希尔排序是稳定的算法。(2分)

F

R1-4

某二叉树的后序和中序遍历序列正好一样,则该二叉树中的任何结点一定都无左孩子。(2分)

F

R1-5

Kruskal 算法是维护一个森林,每一步把两棵树合并成一棵。(2分)

T

R1-6

在具有N个结点的单链表中,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N)。(2分)

F

R1-7

将一棵完全二叉树存于数组中(根结点的下标为1)。则下标为23和24的两个结点是兄弟。(2分)

F

R1-8

如果无向图G必须进行两次广度优先搜索才能访问其所有顶点,则G一定有2个连通分量。(2分)

T

R1-9

即使把2个元素散列到有100个单元的表中,仍然有可能发生冲突。(2分)

T

R1-10

在用数组表示的循环队列中,front值一定小于等于rear值。(2分)

F

R2-1若一棵AVL树有 28 个结点,则该树的最大深度为__。空树的深度定义为0。(3分)

A.7

B.6

C.4

D.5

2-2下列排序方法中,若将顺序存储更换为链式存储,则算法的时间效率会降低的是:

1.插入排序;2.选择排序;3.起泡排序;4.希尔排序;5.堆排序(3分)

A.仅2、3

B.仅1、2

C.仅4、5

R2-3若一棵二叉树的前序遍历序列是{ 4, 2, 1, 3, 6, 5, 7 },中序遍历序列是{ 1, 2, 3, 4, 5, 6, 7 },则下列哪句是错的?(3分)

A.4是3的父结点

B.这是一棵完全二叉树

C.所有的奇数都在叶子结点上

D.这是一棵二叉搜索树

D.仅3、4

R2-4对于一非空的循环单链表,hp分别指向链表的头、尾结点,则有:(3分)

A.p->next == h

B.p == h

C.p->next == NULL

D.p == NULL

R2-5下列程序的时间复杂度为()。

i = 0; s = 0;
while(s < n)
{
  i++;
  s = s + i;
}

(3分)

A.Θ(1)

B.Θ(n2)

C.Θ(n½)

D.Θ(n)

R2-6排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一“趟”。下列序列中,不可能是快速排序第二趟结果的是:(3分)

A.2, 16, 5, 28, 12, 60, 32, 72

B.5, 2, 16, 12, 28, 60, 32, 72

C.2, 12, 16, 5, 28, 32, 72, 60

D.5, 2, 12, 28, 16, 32, 72, 60

R2-7对 n 个互不相同的符号进行哈夫曼编码。若生成的哈夫曼树共有 115 个结点,则 n 的值是:(3分)

A.60

B.57

C.58

D.56

R2-8串 ‘ababaaababaa’ 的next数组为:(3分)

A.011234223456

B.012345678999

C.012121111212

D.0123012322345

R2-9适用于压缩存储稀疏矩阵的两种存储结构是:(3分)

A.三元组表和十字链表

B.邻接矩阵和十字链表

C.十字链表和二叉链表

D.三元组表和邻接矩阵 

R2-10设最小堆(小根堆)的层序遍历结果为 {8, 38, 25, 58, 52, 82, 70, 60}。用线性时间复杂度的算法将该堆调整为最大堆(大根堆),然后连续执行两次删除最大元素操作(DeleteMax)。则该树的中序遍历结果为:(3分)

A.38, 58, 52, 60, 8, 25

B.8, 58, 52, 60, 25, 38

C.8, 58, 60, 32, 25, 38

D.60, 58, 8, 52, 38, 25

R2-11设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是(3分)

A.3

B.1

C.1或者5

D.5

R2-12将元素序列{18,23,11,20,2,7,27,33,42,15}按顺序插入一个初始为空的、大小为11的散列表中。散列函数为:H(Key)=Key%11,采用线性探测法处理冲突。问:当第一次发现有冲突时,散列表的装填因子大约是多少?(3分)

A.0.64

B.0.45

C.0.27

D.0.73

R2-13下图为一个AOV网,其可能的拓扑有序序列为:

(3分)

A.ABCDFE

B.ACBDEF

C.ABCEFD

D.ABCEDF

R2-14

给定一个图的邻接矩阵如下,则从V1出发的宽度优先遍历序列(BFS,有多种选择时小标号优先)是:

6-8.JPG

(3分)

A.V1, V2, V3, V4, V5, V6, V7, V9, V8, V10

B.V1, V2, V3, V5, V7, V9, V10, V6, V8, V4

C.V1, V2, V4, V3, V6, V8, V10, V9, V7, V5

D.V1, V2, V4, V6, V8, V10, V9, V7, V5, V3

R2-15已知二维数组 A 按行优先方式存储,每个元素占用 1 个存储单元。若元素 A[0][0] 的存储地址是 100,A[3][3] 的存储地址是 220,则元素 A[5][5] 的存储地址是:(3分)

A.300

B.306

C.301

D.295

函数题:

R6-1 链表逆置 (10 分)

本题要求实现一个函数,将给定单向链表逆置,即表头置为表尾,表尾置为表头。链表结点定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};

函数接口定义:

struct ListNode *reverse( struct ListNode *head );

其中head是用户传入的链表的头指针;函数reverse将链表head逆置,并返回结果链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *reverse( struct ListNode *head );
void printlist( struct ListNode *head )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode  *head;

    head = createlist();
    head = reverse(head);
    printlist(head);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

1 2 3 4 5 6 -1

结尾无空行

输出样例:

6 5 4 3 2 1 

 代码:

struct ListNode *reverse( struct ListNode *head ){
    struct ListNode *h_reverse=NULL,*p=head,*now;
    while(p){
        now=p->next;
        p->next=h_reverse;
        h_reverse=p;
        p=now;
    }
    return h_reverse;
}//在原链表上进行方向转置

R6-2 求二叉树高度 (10 分)

本题要求给定二叉树的高度。

函数接口定义:

int GetHeight( BinTree BT );

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

要求函数返回给定二叉树BT的高度值。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
int GetHeight( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("%d\n", GetHeight(BT));
    return 0;
}
/* 你的代码将被嵌在这里 */

输出样例(对于图中给出的树):

4

代码:

int GetHeight( BinTree BT )
{
   if (BT==NULL)
    return 0;
    int max;
    max= GetHeight(BT->Left);
    if(max<GetHeight(BT->Right))
        max=GetHeight(BT->Right);
    return max+1;
}

R6-3 有序数组的插入 (15 分)

本题要求将任一给定元素插入从大到小排好序的数组中合适的位置,以保持结果依然有序。

函数接口定义:

bool Insert( List L, ElementType X );

其中List结构定义如下:

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较,并且题目保证传入的数据是递减有序的。函数Insert要将X插入Data[]中合适的位置,以保持结果依然有序(注意:元素从下标0开始存储)。但如果X已经在Data[]中了,就不要插入,返回失败的标记false;如果插入成功,则返回true。另外,因为Data[]中最多只能存MAXSIZE个元素,所以如果插入新元素之前已经满了,也不要插入,而是返回失败的标记false

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 10
typedef enum {false, true} bool;
typedef int ElementType;

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

List ReadInput(); /* 裁判实现,细节不表。元素从下标0开始存储 */
void PrintList( List L ); /* 裁判实现,细节不表 */
bool Insert( List L, ElementType X );

int main()
{
    List L;
    ElementType X;

    L = ReadInput();
    scanf("%d", &X);
    if ( Insert( L, X ) == false )
        printf("Insertion failed.\n");
    PrintList( L );

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1:

5
35 12 8 7 3
10

结尾无空行

输出样例1:

35 12 10 8 7 3
Last = 5

结尾无空行

输入样例2:

6
35 12 10 8 7 3
8

结尾无空行

输出样例2:

Insertion failed.
35 12 10 8 7 3
Last = 5

代码: 

bool Insert( List L, ElementType X )
 {
     int i = 0;
     if(L->Last == MAXSIZE-1)    //元素已满,无法插入
         return false;
    
     for(; i <= L->Last; ++i)
     {
         if(X == L->Data[i])
             return false;
             
         else if(X < L->Data[i])
             continue;
         else   //if(X > L->Data[i])
         {
             for(int j = L->Last + 1; j >= i+1; --j)  //把插入的位置之后的元素全部向后移动一个位置
             {
                 L->Data[j] = L->Data[j-1];
             }
            L->Data[i] = X;
             ++L->Last;
            return true;
         }
     }
     L->Data[i] = X;    //X为最小值时,跳出循环
++L->Last;
     return true;
 }

编程题:

R7-1 帅到没朋友 (15 分)

当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友。本题就要求你找出那些帅到没有朋友的人。

输入格式:

输入第一行给出一个正整数N(≤100),是已知朋友圈的个数;随后N行,每行首先给出一个正整数K(≤1000),为朋友圈中的人数,然后列出一个朋友圈内的所有人——为方便起见,每人对应一个ID号,为5位数字(从00000到99999),ID间以空格分隔;之后给出一个正整数M(≤10000),为待查询的人数;随后一行中列出M个待查询的ID,以空格分隔。

注意:没有朋友的人可以是根本没安装“朋友圈”,也可以是只有自己一个人在朋友圈的人。虽然有个别自恋狂会自己把自己反复加进朋友圈,但题目保证所有K超过1的朋友圈里都至少有2个不同的人。

输出格式:

按输入的顺序输出那些帅到没朋友的人。ID间用1个空格分隔,行的首尾不得有多余空格。如果没有人太帅,则输出No one is handsome

注意:同一个人可以被查询多次,但只输出一次。

输入样例1:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
8
55555 44444 10000 88888 22222 11111 23333 88888

结尾无空行

输出样例1:

10000 88888 23333

结尾无空行

输入样例2:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
4
55555 44444 22222 11111

输出样例2:

No one is handsome

代码:

#include<iostream>
using namespace std;
int a[1000000];
int main(){
    int n,m,ID,flag=1,t=1;
    cin>>n;
    for(int i=0;i<n;i++){
        int num;
        cin>>num;
        for(int j=0;j<num;j++){
            cin>>ID;
            if(num>1) a[ID]=1;
        }
    }
    cin>>m;
    for(int i=0;i<m;i++){
        cin>>ID;
        if(a[ID]==0){
            if(flag){
                printf("%05d",ID);
                a[ID]=1;
                flag=0;
                t=0;
            }else{
                printf(" %05d",ID);
                a[ID]=1;
                t=0;
            }
        }
    }
    if(t)cout<<"No one is handsome";
    cout<<endl;
    
    return 0;
}

R7-2 一元多项式求导 (15 分)

设计函数求一元多项式的导数。

输入格式:

以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。

输入样例:

3 4 -5 2 6 1 -2 0

结尾无空行

输出样例:

12 3 -10 1 6 0

 代码:

#include<stdio.h>
#define N 1000
struct PolyNode
{
	int coef;
	int ex;
}p[N];
int main()
{
	char  c;
	int size=0,i,c1,e1;
	int cnt=0; //用来标记输出的次数 
	scanf("%d %d",&p[0].coef,&p[0].ex);
	size++;
	while((c=getchar())!='\n')
	{
		scanf("%d %d",&c1,&e1);
		for(i=0;i<size;i++)
		{
			if(e1==p[i].ex)
			{
				p[i].coef=c1;
				break;
			}
		}
		if(i==size)
		{
			p[size].coef=c1;
			p[size].ex=e1;
			size++;
		}
	}
	for(i=0;i<size;i++)
	{
		p[i].coef=p[i].coef*p[i].ex;
		p[i].ex-=1;
	}
	for(i=0;i<size;i++)
	{
		if(cnt==0&&p[i].coef!=0)
		{
			printf("%d %d",p[i].coef,p[i].ex);
			cnt++;
		}
		else if(cnt!=0&&p[i].coef!=0)
		{
			printf(" %d %d",p[i].coef,p[i].ex);
			cnt++;
		}
	}
	if(cnt==0)
	{
		printf("0 0");
	}
	
}

  • 11
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

《缱绻》

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值