山东科技大学2017年数据结构期末考试题(判断&&选择&&函数&&编程)(试卷整理)

山东科技大学2017年数据结构期末考试题(判断&&选择&&函数&&编程)(试卷整理)
一、判断题
1-1
图的关键路径上任意活动的延期都会引起工期的延长。

解: 在关键路径上任意活动延期均会影响工期!正确!

1-2
所有的排序算法中,关键字的比较操作都是不可避免的。

解: 不对,基数排序不是基于比较实现的。 错误!

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

解: 前序:中 左 右 中序:左 中 右 如果前序与中序一样,则均没有左孩子,正确!

1-4
折半查找的判定树一定是平衡二叉树。 (2分)

解: 折半查找的判定树一定是平衡二叉树,正确!

1-5
查找某元素时,折半查找法的查找速度一定比顺序查找法快。 (2分)

解: 未必!错误!

1-6
用邻接矩阵法存储图,占用的存储空间数只与图中结点个数有关,而与边数无关。 (2分)

解: 对!O(n^2),与边数无关,正确!

1-7
基于比较的排序算法中,只要算法的最坏时间复杂度或者平均时间复杂度达到了次平方级O(N * logN),则该排序算法一定是不稳定的。 (2分)

解: Mergesort就是稳定的!最坏时间复杂度为次平方阶的,错误!

1-8
B-树中一个关键字只能在树中某一个节点上出现,且节点内部关键字是有序排列的。 (2分)

解:正确的,B树的重要性质!

1-9
采用顺序存储结构的循环队列,出队操作会引起其余元素的移动。 (2分)

解: 明显不对,顺序循环队列,根本就不涉及元素移动!只是front与rear在移动! 错误!

1-10
二叉树中至少存在一个度为2的结点。 (2分)

解: 错误,左单枝or右单枝,没有度为2得结点!错误!
二、选择题
2-1
下面代码段的时间复杂度是()。 (3分)
i=1;
while( i<=n )
i=i*3;
A. O(n)
B. O(n^2)
C. O(1)
D. O(log3n)

解: 明显D;

2-2
设一段文本中包含4个对象{a,b,c,d},其出现次数相应为{4,2,5,1},则该段文本的哈夫曼编码比采用等长方式的编码节省了多少位数? (3分)
A. 5
B. 0
C. 2
D. 4

解: 等长编码:24; Huffman编码:22; 24-22=2;

2-3
在双向循环链表结点p之后插入s的语句是: (3分)
A. s->prior=p;s->next=p->next; p->next=s; p->next->prior=s;
B. p->next=s;s->prior=p; p->next->prior=s ; s->next=p->next;
C. p->next->prior=s;p->next=s; s->prior=p; s->next=p->next;
D. s->prior=p;s->next=p->next; p->next->prior=s; p->next=s;

解: 注意事项 1)先连那个结点就先修改谁的指针域; 2)先对p->next->prior进行修改,再修改p->next; 选D!!!

2-4下图为一个AOV网,其可能的拓扑有序序列为: (3分)A.     ABCDFEB.     ABCEDFC.    ACBDEFD.    ABCEFD

解:明显是A B C E D F选D;

2-5
对于模式串’abaaab’,利用KMP算法进行模式匹配时,其对应的Next取值(注意是未改进的Next值)为: (3分)
A. 0 1 1 2 3 1
B. 01 1 2 2 2
C. 0 1 2 3 4 5
D. 0 1 2 2 2 1

解: J= 1 2 3 4 5 6 String=a b a a a b Next=0 1 1
2 2 2 选B;

2-6
给定散列表大小为11,散列函数为H(Key)=Key%11。采用平方探测法处理冲突:h​i​​(k)=(H(k)±i^2)%11将关键字序列{ 6,25,39,61 }依次插入到散列表中。那么元素61存放在散列表中的位置是: (3分)
A. 5
B. 6
C. 7
D. 8
解:
在这里插入图片描述

61存放在5号单元! 选A;

2-7
设栈S和队列Q的初始状态均为空,元素a、b、c、d、e、f、g依次进入栈S。若每个元素出栈后立即进入队列Q,且7个元素出队的顺序是b、d、c、f、e、a、g,则栈S的容量至少是: (3分)
A. 3
B. 4
C. 1
D. 2

解: 选A; 模拟一下整个过程!入栈顺序:a,b,c,d,e,f,g;
出栈顺序:b,d,c,f,e,a,g; 最大的时候栈长为3;选A;

2-8
有组记录的排序码为{46,79,56,38,40,84 },采用快速排序(以位于最左位置的对象为基准而)得到的第一次划分结果为: (3分)
A. {38,79,56,46,40,84}
B. {38,46,56,79,40,84}
C. {38,46,79,56,40,84}
D. {40,38,46,56,79,84}

解: 设个low(左指针) 设个high(右指针) 先从右到左找比基准小的,填之,high–; 再从左到右找比基准大的,填之,low++;
直到low==high,填入基准!第一趟结束!!! 选D;

2-9
设森林F中有三棵树,第一、第二、第三棵树的结点个数分别为M1,M2和M3。则与森林F对应的二叉树根结点的右子树上的结点个数是: (3分)
A.M1+M2​​
B.M2+M3​​
C.M1​​
D.M3

解: 树转化为森林: 根结点右边是其它树,一刀切,右边结点数为:M2+M3;选B;

2-10
在决定选取何种存储结构时,一般不考虑()。 (3分)
A. 结点个数的多少
B. 对数据有哪些运算
C. 所用编程语言实现这种结构是否方便
D. 各结点的值如何

解: 采用何种存储结构一般不考虑结点的值如何! 选D;

2-11
将{ 3, 8, 9, 1, 2, 6 }依次插入初始为空的二叉排序树。则该树的后序遍历结果是: (3分)
A. 1, 2, 8,6, 9, 3
B. 2,1, 6, 9, 8, 3
C. 1, 2, 3,6, 9, 8
D. 2, 1, 3,6, 9, 8

解: 选B;

2-12
具有65个结点的完全二叉树其深度为(根的深度为1): (3分)
A. 6
B. 5
C. 8
D. 7

解: 2^6-1<65; 2^7-1>65; 选D;

2-13
在图中自d点开始进行深度优先遍历算法可能得到的结果为: (3分)
A. d,e,a,c,f,b
B. d,f,c,e,a,b
C. d,a,c,f,e,b
D. d,a,e,b,c,f

解://这个题没有找到母题,在你们的PTA上应该有原题!

2-14
我们用一个有向图来表示航空公司所有航班的航线。下列哪种算法最适合解决找给定两城市间最经济的飞行路线问题? (3分)
A. Kruskal算法
B. Dijkstra算法
C. 深度优先搜索
D. 拓扑排序算法

解: 解决单源最短路问题,要用迪杰斯特拉算法! 选B;

2-15
若对N阶对称矩阵A以行优先存储的方式将其下三角形的元素(包括主对角线元素)依次存放于一维数组B[1…(N(N+1))/2]中,则A中第i行第j列(i和j从1开始,且i>j)的元素在B中的位序k(k从1开始)为 (3分)
A. j*(j-1)/2+i
B. i*(i+1)/2+j
C. j*(j+1)/2+i
D. i*(i-1)/2+j

解: 直接套公式,选D;

三、函数题
函数题

6-1 删除单链表中最后一个与给定值相等的结点 (10 分)

本题要求在链表中删除最后一个数据域取值为x的节点。L是一个带头结点的单链表,函数ListLocateAndDel_L(LinkList L, ElemType x)要求在链表中查找最后一个数据域取值为x的节点并将其删除。例如,原单链表各个节点的数据域依次为1 3 1 4 3 5,则ListLocateAndDel_L(L,3)执行后,链表中剩余各个节点的数据域取值依次为1 3 1 4 5。

函数接口定义:

void ListLocateAndDel_L(LinkList L, ElemType x);

其中 L 是一个带头节点的单链表。 x 是一个给定的值。函数须在链表中定位最后一个数据域取值为x的节点并删除之。

裁判测试程序样例:

 
//库函数头文件包含
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2
#define NULL        0

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;
//链表创建函数
Status ListCreate_L(LinkList &L,int n){
    LNode *rearPtr,*curPtr;
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;
    rearPtr=L;
    for (int i=1;i<=n;i++){
        curPtr=(LNode*)malloc(sizeof(LNode));
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);
        curPtr->next=NULL;
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
//链表输出函数
void ListPrint_L(LinkList L)
{
LNode *p=L->next;
if(!p){
    printf("空表");
    return;
}
while(p!=NULL)
{
       if(p->next!=NULL)
           printf("%d ",p->data);
       else
           printf("%d",p->data);
       p=p->next;
}
}
//下面是需要实现的函数的声明
void ListLocateAndDel_L(LinkList L, ElemType x);
int main()
{
    LinkList L;
    int n;
    int x;
    scanf("%d",&n);  //输入链表中元素个数
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
   scanf("%d",&x); //输入待查找元素
   ListLocateAndDel_L(L,x);
   ListPrint_L(L);
   return 0;
}
/* 请在这里填写答案 */

输入样例:

6

1 3 1 4 3 5

3

输出样例:

1 3 1 4 5

思路:

设两组指针,一组记录最后一个值为X的结点的地址
一组用来遍历!

答案:

void ListLocateAndDel_L(LinkList L, ElemType x){
	LNode *real_p=NULL;//记录最后一个值为X的结点的地址
	LNode *real_q=NULL;//记录前驱结点的地址
	LNode *p=L->next;
	LNode *q=L;
	while(p){
		if(p->data==x){//每次找到就更新一次
			real_p=p;
			real_q=q;
		}
		p=p->next;
		q=q->next;
	}
	if(real_p&&real_q){//只有二者均不空时才删
		real_q->next=real_p->next;
		free(real_p);
	}
}

6-2 计算二叉树的深度 (10 分)

编写函数计算二叉树的深度。二叉树采用二叉链表存储结构

函数接口定义:

int GetDepthOfBiTree ( BiTree T);

其中 T是用户传入的参数,表示二叉树根节点的地址。函数须返回二叉树的深度(也称为高度)。

裁判测试程序样例:

//头文件包含
#include<stdlib.h>
#include<stdio.h 
#include<malloc.h>

//函数状态码定义
#define TRUE       1
#define FALSE      0
#define OK         1
#define ERROR      0
#define OVERFLOW   -1
#define INFEASIBLE -2
#define NULL  0
typedef int Status;
 
//二叉链表存储结构定义
typedef int TElemType;
typedef struct BiTNode{
    TElemType data;
    struct BiTNode  *lchild, *rchild 
} BiTNode, *BiTree;

//先序创建二叉树各结点,输入0代表空子树
Status CreateBiTree(BiTree &T){
   TElemType e;
   scanf("%d",&e);
   if(e==0)T=NULL;
   else{
     T=(BiTree)malloc(sizeof(BiTNode));
     if(!T)exit(OVERFLOW);
     T->data=e;
     CreateBiTree(T->lchild);
     CreateBiTree(T->rchild);
   }
   return OK; 
}
//下面是需要实现的函数的声明
int GetDepthOfBiTree ( BiTree T);
 
//下面是主函数
int main(){
   BiTree T;
   int depth;
   CreateBiTree(T);
   depth= GetDepthOfBiTree(T);  
   printf("%d\n",depth);
}
/* 请在这里填写答案 */

思路:

递归思想
找好递归边界
找好递归关系

答案:

int GetDepthOfBiTree ( BiTree T ){
    if(!T)return 0;
    else{
        int left=GetDepthOfBiTree (T->lchild);
        int right=GetDepthOfBiTree (T->rchild);
        if(left>right)return 1+left;
        else          return 1+right;
    }
}

编程题

7-1 排序 (15 分)

给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。

本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

· 数据1:只有1个元素;
· 数据2:11个不相同的整数,测试基本正确性;
· 数据3:103个随机整数;
· 数据4:104个随机整数;
· 数据5:105个随机整数;
· 数据6:105个顺序整数;
· 数据7:105个逆序整数;
· 数据8:105个基本有序的整数;
· 数据9:105个随机正整数,每个数字不超过1000。

输入格式:

输入第一行给出正整数N(≤10​5​​),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。

输出格式:

在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。

输入样例:

11

4 981 10 -17 0 -20 29 50 8 43 -5

输出样例:

-20 -17 -5 0 4 8 10 29 43 50 981

思路:

shellsort实现
出这个题,,,就是在送分,10000ms
写一个冒泡就能的一半多的分数

用shellsort是通过所有测试点的
这里用的shellsort

答案:

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

void shellinsert(int *a,int n,int dk){
    int temp;
    for(int i=dk;i<n;i+=dk){//希尔插入函数
        if(a[i]<a[i-dk]){
            temp=a[i];
            int j;
            for(j=i-dk;j>=0&&a[j]>temp;j-=dk){
                a[j+dk]=a[j];
            }
            a[j+dk]=temp;
        }
    }
}

void shellsort(int *a,int n){//希尔排序函数
    int dk[13]={10000,5000,2500,1000,500,250,125,75,30,15,8,4,1};
    for(int i=0;i<13;i++){
        shellinsert(a,n,dk[i]);
    }
}

int main(){
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    shellsort(a,n);
    int flag=0;
    for(int i=0;i<n;i++){
        if(flag==1){
            printf(" %d",a[i]);
        }else{
            flag=1;
            printf("%d",a[i]);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值