2023成电信软互加程算II 期末考试

基本情况

对应课程:程序设计与算法基础II(数据结构与算法基础)

考试时间:3小时(2023-06)

题型:函数题

因为这次考试的题目全部写入了markdown文档,无法直接在icoding查看,仅仅能从一些注释看出考察内容。因此题目并无原文


考题

保留线性表的偶数

题目编号:197

#include "exam202306.h"
//main函数,启动测试函数
int main() {
    extern int q1(); //已写好的测试函数
    return q1();
}

//-------------------------------------------------------------------
//你的代码写在这一下。前面的代码请勿修改!!!

/* 
 * @brief   在线性表L中仅保留偶数。
 * 
 * @param   L:指向线性表的指针,保证不空
 * 
 * @return  void
 */
void keep_even(list *L) {
    //TODO
}

参考答案:

void keep_even(list *L) {
    //TODO
    
    int i, j = 0;

    // 遍历线性表,将偶数移到前面
    for (i = 0; i < L->len; i++) {
        if (L->elem[i] % 2 == 0) {
            L->elem[j++] = L->elem[i];
        }
    }

    // 更新线性表长度
    L->len = j;

}

不用递归的先序遍历

题目编号:198

#include "exam202306.h"



//声明访问二叉树结点的访问函数,参数是结点的字母标签
extern void visit(char); 

//声明外部栈(指针)
//S栈已经初始化了,在你的代码中直接使用即可
extern stack *S;

//main函数,启动测试函数
int main() {
    extern int q2(); //已写好的测试函数
    return q2();
}

//-------------------------------------------------------------------
//你的代码写在这一下。前面的代码请勿修改!!!

/*
 * @brief   不用递归,实现二叉树的先序遍历。
 *
 * @param   tree:指向二叉树根结点的指针。注意:可能是空树!!!
 *
 * @return  void
 */
void preorder(bitree tree) {
    //TODO
}

参考答案:

void preorder(bitree tree) {
    if (tree == NULL) {
        return;
    }

    stack_init(S); // 初始化栈
    stack_push(S, tree); // 根结点入栈

    while (!stack_empty(S)) {
        bitree node = stack_pop(S);
        stack_push(S,node);
        stack_pop(S);

        visit(node->tag); // 访问结点

        // 先将右子树入栈,再将左子树入栈
        if (node->right != NULL) {
            stack_push(S, node->right);
        }
        if (node->left != NULL) {
            stack_push(S, node->left);
        }
    }
}

解决冲突的hash表

题目编号:199

创建一个使用链址法解决键值冲突问题的Hash表

#include "exam202306.h"



//main函数,启动测试函数
int main() {
    extern int q3(); //已写好的测试函数
    return q3();
}

//-------------------------------------------------------------------
//你的代码写在这一下。前面的代码请勿修改!!!

/*
 * @brief   创建一个使用链址法解决键值冲突问题的Hash表
 * 如果散列时出现冲突,那么需要
 * 1. 为新结点分配内存
 * 2. 将键值存入新结点的数据域
 * 3. 将新结点用头插法插入链表中
 *
 * @param   ht:Hash表。实际上是一个指针数组,每个指针是一个单链表的头指针。
 * @param   keys:包含待散列的键值的数组
 * @param   n:keys数组的长度。注意:这不是ht的长度!!!ht的长度为P
 *
 * @return  void
 */
void hashing(hashnode *ht[], int *keys, int n) {
    //TODO
}

参考答案:

void hashing(hashnode *ht[], int *keys, int n) {
    //TODO
    for (int i = 0; i < n; i++) {
        // 创建新结点
        hashnode *newnode = (hashnode *)malloc(sizeof(hashnode));
        newnode->key = keys[i];
        newnode->next = NULL;

        // 计算散列值并插入链表
        int hashval = keys[i] % P;
        if (ht[hashval] == NULL) {
            // 头结点为空,则直接插入链表
            ht[hashval] = newnode;
        } else {
            // 头结点不为空,头插法插入链表
            newnode->next = ht[hashval];
            ht[hashval] = newnode;
        }
    }
}

判断欧拉图

题目编号:200

题目大意:判断有向图中是否存在欧拉通路

#include "exam202306.h"

//main函数,启动测试函数
int main() {
    extern int q4(); //已写好的测试函数
    return q4();
}

//-------------------------------------------------------------------
//你的代码写在这一下。前面的代码请勿修改!!!

/*
 * @brief   判断有向图中是否存在欧拉通路
 *
 * @param   G:邻接矩阵表示的有向图
 *
 * @return  bool:欧拉通路存在返回true,否则返回false
 */
bool if_eulerpath(adjmatrix *G) {
    //TODO
}

参考满分答案:

int n = G->vexnum;  // 图中顶点的个数

    // 统计每个顶点的入度和出度
    int *indegree = (int *)malloc(n * sizeof(int));
    int *outdegree = (int *)malloc(n * sizeof(int));

    for (int i = 0; i < n; i++) {
        indegree[i] = 0;
        outdegree[i] = 0;
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (G->arcs[i][j] != 0) {
                outdegree[i]++;
                indegree[j]++;
            }
        }
    }

    // 判断是否满足欧拉通路的条件
    int start_count = 0;  // 入度比出度大1的顶点的个数
    int end_count = 0;    // 出度比入度大1的顶点的个数
    int diff_count = 0;   // 入度与出度之差大于1的顶点的个数

    for (int i = 0; i < n; i++) {
        if (indegree[i] - outdegree[i] > 1 || outdegree[i] - indegree[i] > 1) {
            return false;  // 入度和出度之差大于1,不满足条件
        } else if (indegree[i] - outdegree[i] == 1) {
            start_count++;
        } else if (outdegree[i] - indegree[i] == 1) {
            end_count++;
        }
    }

    // 欧拉路径的起点和终点必须满足以下条件之一:
    // 1. 没有入度比出度大1的顶点和出度比入度大1的顶点
    // 2. 只有一个入度比出度大1的顶点和一个出度比入度大1的顶点,且它们的个数分别为1
    if (!(start_count == 0 && end_count == 0) && !(start_count == 1 && end_count == 1)) {
        return false;
    }

    return true;

有序数组合并

题目编号:201

题意:将两个已经有序的数组a和b合并到数组c中。合并后的c也是有序的

#include "exam202306.h"



//main函数,启动测试函数
int main() {
    extern int q5(); //已写好的测试函数
    return q5();
}

//-------------------------------------------------------------------
//你的代码写在这一下。前面的代码请勿修改!!!

/*
 * @brief   将两个已经有序的数组a和b合并到数组c中。合并后的c也是有序的
 * 
 * @param   a:源数组1,已经升序排序
 * @param   lena:数组a的长度
 * @param   b:源数组2,已经升序排序
 * @param   lenb:数组b的长度
 * @param   c:保存合并后有序序列的数组
 *
 * @return  void
 */
void merge_2in1(const int *a, int lena, const int *b, int lenb, int *c) {
    //TODO
}

参考满分答案:

void merge_2in1(const int *a, int lena, const int *b, int lenb, int *c) {
    //TODO
    int i = 0;  // 指向数组 a 的索引
    int j = 0;  // 指向数组 b 的索引
    int k = 0;  // 指向数组 c 的索引

    while (i < lena && j < lenb) {
        if (a[i] <= b[j]) {
            c[k] = a[i];
            i++;
        } else {
            c[k] = b[j];
            j++;
        }
        k++;
    }

    while (i < lena) {
        c[k] = a[i];
        i++;
        k++;
    }

    while (j < lenb) {
        c[k] = b[j];
        j++;
        k++;
    }
}

填空

题目编号:202

#include 

//main函数
int main() {
    //直接将要求输出的内容写在printf的()中,不加\n
    printf(/*TODO*/);

    return 0;
}

本题正确答案为:(a3,0)(a6,38)(a8,87)(a9,151)

不知道这个题考的啥....


声明

本文章仅供学习使用。严禁作其他用途。

你可能感兴趣的:(成电信软程算期末机考题,程序设计与算法基础,数据结构,开发语言)