华水967数据结构2024真题(回忆版)

一、 选择[10道) (20分).

1、数据结构中,从逻辑结构上可以把数据结构分为()

答案:线性结构和非线性结构

2、给了一个二叉树的中序遍历,求二叉树的后序遍历

解析:
要根据中序遍历的结果来推导后序遍历,需要知道二叉树的根节点。假设中序遍历的结果为inorder = [D, B, E, A, F, C, G],我们可以通过以下步骤来推导后序遍历:
步骤 1: 找到根节点
后序遍历的最后一个元素是根节点。假设我们知道根节点是 A。
步骤 2: 分割中序遍历
在中序遍历中找到根节点 A,将数组分成左子树和右子树:
左子树的中序遍历:[D, B, E]
右子树的中序遍历:[F, C, G]
步骤 3: 分割前序遍历
假设我们也有前序遍历的结果 preorder = [A, B, D, E, C, F, G],可以通过前序遍历来确定左右子树的根节点:
左子树的根节点是 B
右子树的根节点是 C
步骤 4: 递归处理左右子树
左子树
中序遍历:[D, B, E]
前序遍历:[B, D, E]
找到左子树的根节点 B,分割中序遍历:
左子树的中序遍历:[D]
右子树的中序遍历:[E]
递归处理:
左子树的根节点是 D,没有子节点
右子树的根节点是 E,没有子节点
右子树
中序遍历:[F, C, G]
前序遍历:[C, F, G]
找到右子树的根节点 C,分割中序遍历:
左子树的中序遍历:[F]
右子树的中序遍历:[G]
递归处理:
左子树的根节点是 F,没有子节点
右子树的根节点是 G,没有子节点
步骤 5: 合并结果
根据后序遍历的定义(左子树、右子树、根节点),我们可以从下往上合并结果:
左子树的后序遍历:[D, E, B]
右子树的后序遍历:[F, G, C]
整棵树的后序遍历:[D, E, B, F, G, C, A]

3、关于邻接表和邻接矩阵适用于稠密图/稀疏图的问题

解析:
邻接表适用于的情况
稀疏图:邻接表在存储稀疏图时更为节省空间。稀疏图的特点是边数远小于顶点数平方,因此使用邻接表可以避免为不存在的边分配空间。
应用场景:邻接表适用于边的数量远小于顶点数的平方的图,如社交网络、网络路由等。

邻接矩阵适用于的情况
稠密图:邻接矩阵在存储稠密图时更为高效。稠密图的特点是边数接近于顶点数平方,使用邻接矩阵可以直接通过矩阵访问判断两个顶点之间是否有边,时间复杂度为O(1)。
应用场景:邻接矩阵适用于边的数量接近于顶点数的平方的图,如完全图、密集网络等

4、给了一个二维数组A[M][N],计算另外一个数组的地址 例;设有A[6][5]数组,每数组占四个字节,告诉了起始地址,计算A[2][3]。

5、考查广义表head和tail方法使用 例;设广表A=(x,((a,b),c,d))。求Head (Head (Tail(A)))=?

解析:
Tail(A):
A 的尾部是从第二个元素开始的所有元素。
A = (x, ((a, b), c, d)),所以 Tail(A) = (((a, b), c, d))。
Head(Tail(A)):
Tail(A) = (((a, b), c, d)),其头部是第一个元素。
因此,Head(Tail(A)) = (c, d)。
Head(Head(Tail(A))):
Head(Tail(A)) = (c, d),其头部是第一个元素。
所以,Head(Head(Tail(A))) = ©。

6、中缀表达式和后缀表达式的转换

解析:
中缀表达式转后缀表达式
转换中缀表达式到后缀表达式的过程通常使用栈来实现。以下是转换的步骤:
1.初始化一个空栈和空的后缀表达式列表。
2.从左到右扫描中缀表达式的每个字符:
如果字符是操作数(数字或变量),直接添加到后缀表达式列表。
如果字符是左括号 (,压入栈。
如果字符是右括号 ),弹出栈中的元素直到遇到左括号 (,并将这些元素添加到后缀表达式列表。
如果字符是操作符(如 +, -, *, /),弹出栈中优先级大于或等于当前操作符的所有操作符,并将它们添加到后缀表达式列表,然后将当前操作符压入栈。
3.扫描完所有字符后,将栈中剩余的所有操作符弹出并添加到后缀表达式列表。

其他的记不清了, 24年选择题不难,都是往年真题迭择题中的基础题。

二、 简答题 (共3小问、20分)

1、 简述头指针、头结点、首元结点。

解析:

头指针

定义:头指针是指向链表第一个结点的指针。它并不存储任何数据,只是用来标识链表的起始位置。
作用:头指针是链表的必要元素,它允许我们访问链表中的第一个元素,从而开始遍历整个链表。

头结点

定义:头结点是链表中的一个特殊节点,它位于链表的最开始位置,但通常不存储实际的数据,而是作为链表的一个标识。
作用:头结点的主要作用是为链表提供一个统一的起点,使得链表的操作更加方便。它的存在使得在链表头部进行插入和删除操作时,不需要特别处理空链表的情况。

首元结点

定义:首元结点,也称为第一个元素结点,是链表中实际存储数据的第一个节点。
作用:首元结点是链表中的实际起始点,它后面跟随的是链表中的其他元素。通过首元结点,可以开始遍历链表并访问其数据。

2、 简述树(不是二叉树的三种存储结构,并说明其各自优缺点。

解析:
树(非二叉树)的三种存储结构分别是双亲表示法、孩子表示法和孩子兄弟表示法。以下是它们的优缺点:

双亲表示法

优点:可以很快得到每个结点的双亲结点。
缺点:求结点的孩子时需要遍历整个结构。

孩子表示法

优点:可以很快找到某个结点的所有子女(遍历该结点的孩子链表即可)。
缺点:寻找双亲操作需要遍历每个结点的孩子链表。

孩子兄弟表示法

优点:存储灵活,树转换为二叉树操作实现方便,易于查找结点的孩子等。
缺点:不易从当前结点查找其双亲结点(可以为每个结点增设一个parent域指向其父亲结点,但需要额外的空间开销)

3、详细写出堆排序的过程(题目给了一串数字)。

解析:
堆排序是一种基于二叉堆数据结构的比较排序算法,其基本思想是将待排序的序列构造成一个大顶堆(或小顶堆),然后将堆顶元素(最大值或最小值)与末尾元素交换,再调整剩余部分为新的堆,重复这个过程直到整个序列有序。以下是堆排序的详细过程:
堆排序的基本步骤
1.构建初始堆:将无序数组构造成一个大顶堆(或小顶堆)。这个过程通常从最后一个非叶子节点开始,向上遍历每个节点,如果节点的值小于其子节点的值,则将该节点与其子节点中值较小的一个交换,直到该节点满足大顶堆的条件。

2.堆排序:将堆顶元素(最大值或最小值)与堆的最后一个元素交换,此时末尾元素就成了最大值(或最小值)。然后将剩余元素重新构成一个堆,重复上述过程,直到堆中只剩下一个元素。
3.重复步骤2:每次从堆中取出最大(或最小)元素后,调整堆结构,使其重新满足大顶堆(或小顶堆)的性质,直到整个数组有序。

堆排序的时间复杂度和空间复杂度
时间复杂度:堆排序的时间复杂度为O(n log n),其中n是数组的大小。这是因为构建初始堆的时间复杂度为O(n),而每次堆调整的时间复杂度为O(log n),总共需要进行n-1次堆调整。
空间复杂度:堆排序的空间复杂度为O(1),因为它只需要一个额外的栈空间来存储原始数据,不需要额外的存储空间。

三、应用题、(共5题,记得4个)

1、利用栈模拟出算术表达式。(与2017年的综合题第一题类似)

解析:
算法步骤
1.初始化两个栈:一个用于存储操作数(operandStack),另一个用于存储运算符(operatorStack)。但在逆波兰表示法中,通常只需要一个操作数栈。

2.读取表达式:逐个读取表达式中的元素。

3.处理操作数:如果当前元素是数字,则将其压入操作数栈。

4.处理运算符:如果当前元素是运算符,则从操作数栈中弹出所需数量的操作数,执行运算,并将结果压回操作数栈。

5.重复步骤3和4,直到表达式处理完毕。

6.返回结果:表达式处理完毕后,操作数栈顶部的元素即为最终结果。

2、用两种方法求最小生成树,给出过程。

解析:

Prim算法

基本思想:从一个顶点开始,每次选择与当前生成树相连的权值最小的边,直到所有顶点都被包含。
步骤:
1.选择任意一个顶点作为起点,将其加入生成树集合。
2.在剩余未加入的顶点中找到与生成树集合中顶点相连的权值最小的边。
3.将这条边加入生成树集合,并将对应的顶点加入。
4.重复步骤2和3,直到所有顶点都被加入生成树集合。

Kruskal算法

基本思想:按照边的权值从小到大排序,依次选择边,如果这条边连接的两个顶点不在同一个连通分量中,则将它们合并,直到所有顶点都在同一个连通分量中。
步骤:
1.将所有边按权值从小到大排序。
2.初始化一个空集合,用来存放最小生成树的边。
3.依次取出权值最小的边,如果这条边的加入不会形成环,则将其加入最小生成树中。
4.重复步骤3,直到所有顶点都被包含在内。

3、 考查哈希函数,给了一组数据、哈希函数,让画哈希表和求平均查找长度。

4、考查关键路径问题

题中没直接给出图,题的大意是给出了顶点集V=S{a.b,c},边集
E=S{(a,b).(b.c)_},共三问。
第一问:画出这个图。
第二问:求顶点最早开始时间。
第三问:求顶点最晚开始时间。

24题给的不是边的权值,而是顶点完成所需的时间(之前没考)。

四、代码题(共四个,其中一个算是应用题)

1、代码填空题,共五个空。一个空两分,线性表的插入删除。

解析:

// 在指定位置插入元素
int insertElement(SeqList *list, int position, int element) {if (position < 0 || position > list->length || list->length >= MAXSIZE) {return -1; // 插入失败}for (int i = list->length; i > position; i--) {list->data[i] = list->data[i - 1];}list->data[position] = element;list->length++;return 0; // 插入成功
}// 删除指定位置的元素
int deleteElement(SeqList *list, int position) {if (position < 0 || position >= list->length) {return -1; // 删除失败}for (int i = position; i < list->length - 1; i++) {list->data[i] = list->data[i + 1];}list->length--;return 0; // 删除成功
}

2、给了图,让画出迪杰斯特拉的最短路径图。

3、写出查找一个数的代码,若找不出则把这个数插入数据(有序)。

解析:

// 二分查找函数,返回目标值的索引(若存在),否则返回-1
int binarySearch(int arr[], int size, int target) {int left = 0, right = size - 1;while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] == target) {return mid;} else if (arr[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return -1; // 未找到目标值
}// 在有序数组中插入元素,并保持数组有序
void insertSorted(int arr[], int *size, int target) {int index = binarySearch(arr, *size, target);if (index != -1) {// 若已存在目标值,则不进行插入(或根据需要处理)printf("元素 %d 已存在于数组中。\n", target);} else {// 在index位置插入目标值(需移动元素)for (int i = *size; i > index; i--) {arr[i] = arr[i - 1];}arr[index] = target;(*size)++; // 数组大小加1}
}

4、写出把一个二叉树中的结点存储到一个一维数组中的代码。

解析:

// 层序遍历函数,将节点值存储到数组中
void levelOrder(TreeNode* root, int* arr, int* index) {if (root == NULL) return; // 创建一个队列用于层序遍历TreeNode** queue = (TreeNode**)malloc(100 * sizeof(TreeNode*)); // 假设队列大小足够,实际应用中可能需要动态调整int front = 0, rear = 0;// 将根节点入队queue[rear++] = root;// 层序遍历while (front < rear) {TreeNode* currentNode = queue[front++];arr[(*index)++] = currentNode->val; // 将当前节点值存入数组// 左子节点入队if (currentNode->left != NULL) {queue[rear++] = currentNode->left;}// 右子节点入队if (currentNode->right != NULL) {queue[rear++] = currentNode->right;}}// 释放队列内存free(queue);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14152.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI】在Ubuntu中使用docker对DeepSeek的部署与使用

这篇文章前言是我基于部署好的deepseek-r1:8b模型跑出来的 关于部署DeepSeek的前言与介绍 在当今快速发展的技术环境中&#xff0c;有效地利用机器学习工具来解决问题变得越来越重要。今天&#xff0c;我将引入一个名为DeepSeek 的工具&#xff0c;它作为一种强大的搜索引擎&a…

【Kubernetes Pod间通信-第1篇】在单个子网中使用underlay网络实现Pod到Pod的通信

Kubernetes中Pod间的通信 本系列文章共3篇: 【Kubernetes Pod间通信-第1篇】在单个子网中使用underlay网络实现Pod到Pod的通信(本文介绍)【Kubernetes Pod间通信-第2篇】使用BGP实现Pod到Pod的通信【Kubernetes Pod间通信-第3篇】Kubernetes中Pod与ClusterIP服务之间的通信…

Excel 融合 deepseek

效果展示 代码实现 Function QhBaiDuYunAIReq(question, _Optional Authorization "Bearer ", _Optional Qhurl "https://qianfan.baidubce.com/v2/chat/completions")Dim XMLHTTP As ObjectDim url As Stringurl Qhurl 这里替换为你实际的URLDim postD…

MacOS 安装NVM

MacOS 安装NVM 方法一&#xff1a;使用Homebrew安装nvm 打开终端&#xff08;Terminal&#xff09;&#xff0c;输入以下命令安装Homebrew&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装nvm…

采用idea中的HTTP Client插件测试

1.安装插件 采用idea中的HTTP Client插件进行接口测试,好处是不用打开post/swagger等多个软件,并且可以保存测试时的参数,方便后续继续使用. 高版本(2020版本以上)的idea一般都自带这个插件,如果没有也可以单独安装. 2.使用 插件安装完成(或者如果idea自带插件),会在每个Con…

LabVIEW铅酸蓄电池测试系统

本文介绍了基于LabVIEW的通用飞机铅酸蓄电池测试系统的设计与实现。系统通过模块化设计&#xff0c;利用多点传感器采集与高效的数据处理技术&#xff0c;显著提高了蓄电池测试的准确性和效率。 ​ 项目背景 随着通用航空的快速发展&#xff0c;对飞机铅酸蓄电池的测试需求也…

Python----Python高级(并发编程:协程Coroutines,事件循环,Task对象,协程间通信,协程同步,将协程分布到线程池/进程池中)

一、协程 1.1、协程 协程&#xff0c;Coroutines&#xff0c;也叫作纤程(Fiber) 协程&#xff0c;全称是“协同程序”&#xff0c;用来实现任务协作。是一种在线程中&#xff0c;比线程更加轻量级的存在&#xff0c;由程序员自己写程序来管理。 当出现IO阻塞时&#xff0c;…

go语言中的反射

为什么会引入反射 有时我们需要写一个函数&#xff0c;这个函数有能力统一处理各种值类型&#xff0c;而这些类型可能无法共享同一个接口&#xff0c;也可能布局未知&#xff0c;也有可能这个类型在我们设计函数时还不存在&#xff0c;这个时候我们就可以用到反射。 空接口可…

Mac电脑上好用的压缩软件

在Mac电脑上&#xff0c;有许多优秀的压缩软件可供选择&#xff0c;这些软件不仅支持多种压缩格式&#xff0c;还提供了便捷的操作体验和强大的功能。以下是几款被广泛推荐的压缩软件&#xff1a; BetterZip 功能特点&#xff1a;BetterZip 是一款功能强大的压缩和解压缩工具&a…

大学资产管理系统中的下载功能设计与实现

大学资产管理系统是高校信息化建设的重要组成部分&#xff0c;它负责记录和管理学校内所有固定资产的信息。随着信息技术的发展&#xff0c;下载功能成为提高资产管理效率的关键环节之一。 系统架构的设计是实现下载功能的基础。一个良好的系统架构能够确保数据的高效传输和存储…

UnityShader学习笔记——动态效果

——内容源自唐老狮的shader课程 目录 1.原理 2.Shader中内置的时间变量 3.Shader中经常会改变的数据 4.纹理动画 4.1.背景滚动 4.1.1.补充知识 4.1.2.基本原理 4.2.帧动画 4.2.1.基本原理 5.流动的2D河流 5.1.基本原理 5.2.关键步骤 5.3.补充知识 6.广告牌效果 …

Node.js 实现简单爬虫

介绍 爬虫是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。 本文将使用 Nodejs 编写一个简单的爬虫脚本&#xff0c;爬取一个美食网站&#xff0c;获取菜品的标题和图片链接&#xff0c;并以表格的形式输出。 准备工作 1、初始化项目 首先&#xff0…

JVM执行流程与架构(对应不同版本JDK)

直接上图&#xff08;对应JDK8以及以后的HotSpot&#xff09; 这里主要区分说明一下 方法区于 字符串常量池 的位置更迭&#xff1a; 方法区 JDK7 以及之前的版本将方法区存放在堆区域中的 永久代空间&#xff0c;堆的大小由虚拟机参数来控制。 JDK8 以及之后的版本将方法…

2025蓝桥杯JAVA编程题练习Day3

1.黛玉泡茶【算法赛】 问题描述 话说林黛玉闲来无事&#xff0c;打算在潇湘馆摆个茶局&#xff0c;邀上宝钗、探春她们一起品茗赏花。黛玉素来讲究&#xff0c;用的茶杯也各有不同&#xff0c;大的小的&#xff0c;高的矮的&#xff0c;煞是好看。这不&#xff0c;她从柜子里…

p5r预告信生成器API

p5r预告信生成器API 本人将js生成的p5r预告信使用go语言进行了重写和部署&#xff0c;并开放了其api&#xff0c;可以直接通过get方法获取预告信的png。 快速开始 http://api.viogami.tech/p5cc/:text eg: http://api.viogami.tech/p5cc/persona5 感谢p5r风格字体的制作者和…

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件&#xff1a;vsCode和Node&#xff08;本人电脑Win11安装&#xff09; 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装&#xff0c;点击下一步即可 …

软件设计模式

目录 一.创建型模式 抽象工厂 Abstract Factory 构建器 Builder 工厂方法 Factory Method 原型 Prototype 单例模式 Singleton 二.结构型模式 适配器模式 Adapter 桥接模式 Bridge 组合模式 Composite 装饰者模式 Decorator 外观模式 Facade 享元模式 Flyw…

Maven架构项目管理工具

1.1什么是Maven 翻译为“专家”&#xff0c;“内行”Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建&#xff0c;依赖管理和项目信息管理。什么是理想的项目构建&#xff1f; 高度自动化&#xff0c;跨平台&#xff0c;可重用的组件&#xff0c;标准化的 什么…

【Linux】25.进程信号(1)

文章目录 1. 信号入门1.1 进程与信号的相关知识1.2 技术应用角度的信号1.3 注意1.4 信号概念1.5 信号处理常见方式概览 2. 产生信号2.1 通过终端按键产生信号2.2 调用系统函数向进程发信号2.3 由软件条件产生信号2.4 硬件异常产生信号2.5 信号保存 3. 阻塞信号3.1 信号其他相关…

第二个Qt开发实例:在Qt中利用GPIO子系统和sysfs伪文件系统实现按钮(Push Button)点击控制GPIO口(效果为LED2灯的灭和亮)

引言 本文承接博文 https://blog.csdn.net/wenhao_ir/article/details/145420998 里的代码&#xff0c;在那里面代码的基础上添加上利用sysfs伪文件系统实现按钮(Push Button)点击控制GPIO口的代码&#xff0c;进而实现LED2灯的灭和亮。 最终的效果是点击下面的LED按钮实现LED…