2025春新生培训数据结构(树,图)

news2025/4/21 7:54:29

教学目标:

1,清楚什么是树和图,了解基本概念,并且理解其应用场景

2,掌握一种建图(树)方法

3,掌握图的dfs和树的前中后序遍历

例题与习题

2025NENU新生培训(树,图)习题

引言

恭喜各位!当你学到图和树的内容的时候,已经结束了萌新的状态。

大家想来已经早就听过了关于树和图的传说,但树和图到底是什么呢?又有什么用呢?

大家试想一下,我们现在已知的几种数据结构:栈,队列,链表......这些结构都有一个特点,就是线性的。

这些结构里,从前到后点与点之间的关系是1v1的,而我们不妨思考一下在如下情境中我们该如何存储数据,我们要构造一个这样的情景:

有许多的人,我们知道a比b年龄大,a比c大,d比c大,d比e大......该如何记录这样的信息呢?

如果你能独立想明白的话,我想你已经独立想出了算法中的一大突破,那就是树与图。

我们想一下应该怎么办。是不是本能地想到应该记录一下某个人a和所有与a有关系的人?而这显然一个一维数组我们如果用下标来表示是谁,那么一个值通常是存不下来所有和他有关系的人的。因此我们可以用二维数组来存储,用某一维表示a,然后另一维去存与a有关系的人。

举个例子:

已知有三个人a, b, c, 已知a > b, b > c, a > c

我们可以用一个3 * 3 的数组来记录它,用 1 来表示大于

    a  b  c

a  0  1  1

b  0  0  1

c  0  0  0

这就是一个邻接矩阵, 我们可以从中看出 a 比 b 大, a 比 c大, b 比 c 大

然而邻接矩阵会用节点数目的平方的空间,因此这往往并不适用于节点数目较多而边数较少的情况,所以我们往往会采用另一种方式邻接表,在这种数据结构中,我们记录和每一个顶点有关系的点。

这很方便,以上图为例,如果我们用邻接表的方式,我们所记录的大概是这样:

a : b c

b : c

c :

这同样能够记录图的结构,而消耗的空间很小。

第二种方式又有两种不同的建图方法分别是单链表和动态数组,在讲解建图方式之前,我们不如先来系统地讲述一下图和树的基本概念:

树与图的基本概念

一、图 (Graph)


正如我们前面所讲,图是一种由节点(顶点)和边组成的数据结构,通常用于表示复杂的关系。与树不同,图不要求有层次关系,也不一定是连通的。

1. 图的基本概念


顶点 (Vertex):图中的节点。
边 (Edge):连接两个顶点的线,表示它们之间的关系。
有向图 (Directed Graph):边有方向,即从一个顶点指向另一个顶点。

什么样的关系可以由有向图表示?


无向图 (Undirected Graph):边没有方向,表示两个顶点之间的关系是双向的。

什么样的关系可以由无向图表示?


邻接矩阵 (Adjacency Matrix):使用二维数组表示图的结构,适用于稠密图。
邻接表 (Adjacency List):使用链表数组或动态数组表示图的结构,适用于稀疏图。

二、树(Tree)

树是一种特殊的图!树是无环的连通图。
树是一种分层结构的非线性数据结构,由节点和边组成。每个树由一个根节点和零个或多个子树组成。

1. 树的基本概念
节点(Node):树中的每个元素。
根节点(Root):树的最顶端节点,没有父节点。
父节点(Parent):一个节点的直接前驱节点。
子节点(Child):一个节点的直接后继节点。
叶节点(Leaf):没有子节点的节点。
高度(Height):树中节点的层次,根节点的高度为0。
深度(Depth):节点到根节点的距离。


2. 树的类型
二叉树 (Binary Tree):每个节点最多有两个子节点,通常称为左子节点和右子节点。

完全二叉树:从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点都靠左对齐。

建图

建图(树),

我们接下来以这道题为例,从代码的角度来实现一个图的建立,树的建立与图完全一致

一:邻接矩阵建图

节点数量为n

首先创建一个n * n 的二维数组A,初始值默认为0

对每一条由u到v的边,A[u][v] = A[v][u] = 1

二:邻接表建图

动态数组:

创建一个二维动态数组vector<vector<int>> B(n + 1)

对每一条由u到v的边,B[u].push_back(v), B[v].push_back(u)

链表(较难):

这种方法较难,相对来讲比较传统,大家可以自行了解

下面是这道题目的通过代码,希望大家可以先自行尝试解决这道问题

#include <bits/stdc++.h>

using namespace std;

const int N = 1010, M = 1e5 + 10;

// 邻接矩阵
int A[N][N];

// 邻接表
vector<vector<int>> B(N);

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; i ++ )
	{
		int a, b;
		cin >> a >> b;
		
		// 邻接矩阵存储边
		A[a][b] = A[b][a] = 1;
		
		// 邻接表存储边
		B[a].push_back(b);
		B[b].push_back(a);
	}
	
	for (int i = 1; i <= n; i ++ )
	{
		for (int j = 1; j <= n; j ++ )
		{
			cout << A[i][j] << " ";
		}
		cout << endl;
	}
	
	for (int i = 1; i <= n; i ++ )
	{
		// 一个点相关的边的数量等于这个点的度数
		cout << B[i].size() << " ";
		// 题目中要求从小到大输出
		sort(B[i].begin(), B[i].end());
		for (auto b : B[i])
		{
			cout << b << " ";
		}
		cout << endl;
	}
	
	
	return 0;
}

图(树)的深度优先搜索

大家已经学习过在网格图中如何进行搜索,那么在图中该怎么进行搜索呢?我们这里仅讲述dfs,bfs与其类似,大家可以课后自行尝试

在网格图中,我们通常使用上下左右四个方向来进行移动,但是在图和树中,一个点能移动到的位置是所有与其相连的点

我们用邻接表来讲的话,其dfs大概是这样的

// 邻接表
vector<vector<int>> B(N);

// u是当前访问的节点,fa是上一个节点
void dfs(int u, int fa)
{
	// b 是相连的点
	for (auto b : B[u])
	{
		// 如果不是父节点,就移动过去,这避免了在两个点之间反复横跳
		if (b != fa)
		{
			dfs(b, u);
		}
	}
}

二叉树的前中后遍历

在前文中,我们如果要去遍历图,遍历的顺序取决于给出边的顺序

举个例子,如果给出12 13 14, 我们会先访问2, 再访问3,再访问4

如果给出的是 13 12 14, 这个时候,顺序就变为了3 2 4

但是在二叉树中,我们知道一个点可以有左子节点和右子节点,如果我们按照某种顺序去访问其左子节点右子节点和其本身,那么就会得到相对来讲比较特殊的遍历顺序

前序遍历:根结点 ---> 左子树 ---> 右子树

中序遍历:左子树---> 根结点 ---> 右子树

后序遍历:左子树 ---> 右子树 ---> 根结点

如果课堂时间有剩余或者大家学有余力的话,我们不如一起来思考一下这些问题:

如何记录二叉树的左子节点和右子节点?

如果用链表去做的话怎么做邻接表?

在博客开头的情境里,能否根据已有信息排列出一个明确的年龄顺序,什么情况下可以?什么情况下不行?

结语

关于树与图的知识还有很多,欢迎大家有不懂的知识来问学长学姐,希望大家能够通过思考提高自己的思维能力,算法能力猛猛进步!

感谢阅读!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

keil主题(vscode风格)

#修改global.prop文件&#xff0c;重新打开keil即可 # Keil uVision Global Properties File # This file is used to customize the appearance of the editor# Editor Font editor.font.nameConsolas editor.font.size10 editor.font.style0# Editor Colors editor.backgro…

使用Hydra进行AI项目的动态配置管理

引言:机器学习中的超参数调优挑战 在机器学习领域,超参数调优是决定模型性能的关键环节。不同的模型架构,如神经网络中的层数、节点数,决策树中的最大深度、最小样本分割数等;以及各种训练相关的超参数,像学习率、优化器类型、批量大小等,其取值的选择对最终模型的效果…

深入了解 K-Means 聚类算法:原理与应用

引言 在数据科学和机器学习的世界中&#xff0c;聚类是一项非常重要的技术&#xff0c;它帮助我们根据数据的相似性将数据划分为不同的组或簇。聚类算法在许多领域中得到了广泛的应用&#xff0c;如图像处理、市场细分、基因研究等。K-Means 聚类算法作为最常见的无监督学习算…

永磁同步电机无速度算法--反电动势观测器

一、原理介绍 在众多无位置传感器控制方法中&#xff0c;低通滤波反电势观测器结构简单&#xff0c;参数整定容易&#xff0c;易于编程实现。但是该方法估计出的反电势会产生相位滞后&#xff0c;需要在估计永磁同步电机转子位置时进行了相位补偿。 二、仿真模型 在MATLAB/si…

【Linux】命令行参数 | 环境变量(四)

目录 前言&#xff1a; 一、命令行参数&#xff1a; 1.main函数参数 2.为什么有它&#xff1f; 二、环境变量&#xff1a; 1.main函数第三个参数 2.查看shell本身环境变量 3.PATH环境变量 4.修改PATH环境变量配置文件 5.HOME环境变量 6.SHELL环境变量 7.PWD环境变…

java高级(IO流多线程)

file 递归 字符集 编码 乱码gbk&#xff0c;a我m&#xff0c;utf-8 缓冲流 冒泡排序 //冒泡排序 public static void bubbleSort(int[] arr) {int n arr.length;for (int i 0; i < n - 1; i) { // 外层循环控制排序轮数for (int j 0; j < n -i - 1; j) { // 内层循环…

深度剖析数据分析职业成长阶梯

一、数据分析岗位剖析 目前&#xff0c;数据分析领域主要有以下几类岗位&#xff1a;业务数据分析师、商业数据分析师、数据运营、数据产品经理、数据工程师、数据科学家等&#xff0c;按照工作侧重点不同&#xff0c;本文将上述岗位分为偏业务和偏技术两大类&#xff0c;并对…

Web3.py 入门笔记

Web3.py 学习笔记 &#x1f4da; 1. Web3.py 简介 &#x1f31f; Web3.py 是一个 Python 库&#xff0c;用于与以太坊区块链进行交互。它就像是连接 Python 程序和以太坊网络的桥梁。 官方文档 1.1 主要功能 查询区块链数据&#xff08;余额、交易等&#xff09;发送交易与…

NFC拉起微信小程序申请URL scheme 汇总

NFC拉起微信小程序&#xff0c;需要在微信小程序开发里边申请 URL scheme &#xff0c;审核通过后才可以使用NFC标签碰一碰拉起微信小程序 有不少人被难住了&#xff0c;从微信小程序开发社区汇总了以下信息&#xff0c;供大家参考 第一&#xff0c;NFC标签打开小程序 https://…

《Python实战进阶》No 8:部署 Flask/Django 应用到云平台(以Aliyun为例)

第8集&#xff1a;部署 Flask/Django 应用到云平台&#xff08;以Aliyun为例&#xff09; 2025年3月1日更新 增加了 Ubuntu服务器安装Python详细教程链接。 引言 在现代 Web 开发中&#xff0c;开发一个功能强大的应用只是第一步。为了让用户能够访问你的应用&#xff0c;你需…

【JAVA SE基础】抽象类和接口

目录 一、前言 二、抽象类 2.1 抽象类的概念 2.2 抽象类语法 2.3 抽象类特性 2.4 抽象类的作用 三、接口 3.1 什么是接口 3.2 语法规则 3.3 接口使用 3.4 接口特性 3.5 实现多接口 3.6 接口间的继承 四、Object类 4.1 获取对象信息&#xff08; toString() &…

530 Login fail. A secure connection is requiered(such as ssl)-java发送QQ邮箱(简单配置)

由于cs的csdN许多文章关于这方面的都是vip文章&#xff0c;而本文是免费的&#xff0c;希望广大网友觉得有帮助的可以多点赞和关注&#xff01; QQ邮箱授权码到这里去开启 授权码是16位的字母&#xff0c;填入下面的mail.setting里面的pass里面 # 邮件服务器的SMTP地址 host…

计算机毕业设计SpringBoot+Vue.js体育馆使用预约平台(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

MyBatis-Plus 为简化开发而生【核心功能】

文章目录 一、前言二、快速入门1. 入门案例2. 常见注解3. 常见配置 三、核心功能1. 条件构造器2. 自定义 SQL3. Service 接口3.1 基本使用3.2 复杂条件 一、前言 顾名思义&#xff0c;MyBatis-Plus 其实是 MyBatis 的一个加强版&#xff0c;它可以帮助我们快速高效地编写数据库…

【MySQL】(2) 库的操作

SQL 关键字&#xff0c;大小写不敏感。 一、查询数据库 show databases; 注意加分号&#xff0c;才算一句结束。 二、创建数据库 {} 表示必选项&#xff0c;[] 表示可选项&#xff0c;| 表示任选其一。 示例&#xff1a;建议加上 if not exists 选项。 三、字符集编码和排序…

通信原理速成笔记(信息论及编码)

信息论基础 信息的定义与度量 信息是用来消除不确定性的内容。例如&#xff0c;在猜硬币正反的情境中&#xff0c;结果存在正反两种不确定性&#xff0c;而得知正确结果能消除这种不确定性&#xff0c;此结果即为信息。单个事件的信息量&#xff1a;对于离散信源中的事件xi​&…

云和恩墨亮相PolarDB开发者大会,与阿里云深化数据库服务合作

2025年2月26日&#xff0c;备受瞩目的阿里云PolarDB开发者大会于北京嘉瑞文化中心盛大举行&#xff0c;众多行业精英齐聚一堂&#xff0c;共襄技术盛会。云和恩墨作为阿里云重要的生态合作伙伴受邀参会。云和恩墨联合创始人兼技术研究院总经理杨廷琨与阿里云智能数据库产品事业…

Linux下的网络通信编程

在不同主机之间&#xff0c;进行进程间的通信。 1解决主机之间硬件的互通 2.解决主机之间软件的互通. 3.IP地址&#xff1a;来区分不同的主机&#xff08;软件地址&#xff09; 4.MAC地址&#xff1a;硬件地址 5.端口号&#xff1a;区分同一主机上的不同应用进程 网络协议…

AI数据分析:用DeepSeek做数据清洗

在当今数据驱动的时代&#xff0c;数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展&#xff0c;AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行数据清洗。 数据清洗是数据分析的基础&#xff0c;其目的是…

把GB型材库放入solidwork中点击库无法应

1、文件夹的位置要选择对&#xff0c;如下图&#xff1a; 2、文件夹一定要嵌套三层&#xff0c;如下图