链式二叉树的实现

news2024/9/20 1:02:38

在这里插入图片描述

文章目录

  • 🎯引言
  • 👓链式二叉树的实现
    • 1.链式二叉树的结构
    • 2.链式二叉树相关操作实现
      • 2.1源码展示
      • 2.2函数实现详解
        • 2.2.1前中后序遍历
        • 2.2.2二叉树的其他方法实现
        • 2.2.3二叉树的层序遍历和判断是否是完全二叉树
  • 🥇结语

🎯引言

欢迎来到HanLop博客的C语言数据结构初阶系列。在这个系列中,我们将深入探讨各种基本的数据结构和算法,帮助您打下坚实的编程基础。在本篇文章中,我们将探讨另一种重要的二叉树数据结构——链式二叉树(Linked Binary Tree)。不同于顺序结构的二叉树,链式二叉树使用链表节点来存储树中的元素,使其在内存分配和动态调整上具有更大的灵活性。链式二叉树在许多编程问题中都有广泛应用,特别是在递归算法和树遍历等方面。本篇文章将介绍链式二叉树的基本概念、创建方法、基本操作以及其在实际编程中的应用。通过代码示例,您将学会如何在C语言中实现链式二叉树,并理解其优缺点,为进一步学习更复杂的数据结构做好准备。

👓链式二叉树的实现

链式二叉树(Linked Binary Tree)是一种数据结构,它使用链表节点来表示树中的每个元素。每个节点包含一个数据域和两个指针域,分别指向该节点的左子节点和右子节点。这种结构与顺序结构的二叉树不同,它不需要连续的内存空间,因此在动态变化的数据量下具有更好的灵活性和效率。

1.链式二叉树的结构

每个节点通常包括以下部分:

  1. 数据域(Data):存储节点的值或数据。
  2. 左指针域(Left Child):指向左子节点的指针。
  3. 右指针域(Right Child):指向右子节点的指针。
typedef int BTNDataType;
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTNDataType x;
}BTNode;

在上面的C语言结构体定义中,TreeNode是一个二叉树节点,包含一个整数数据域x,以及两个指针leftright,分别指向左子节点和右子节点

2.链式二叉树相关操作实现

2.1源码展示

BinaryTree.h源码

//BinaryTree.h文件中
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
//包含队列的头文件为了实现层序遍历,
//队列需要自己去实现
//队列的实现在之前文章中有讲过
#include "Queue.h"
typedef int BTNDataType;
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTNDataType x;
}BTNode;

//前序遍历
void PerOrder(BTNode* root);
//中序遍历
void InOrder(BTNode* root);
//前序遍历
void PostOrder(BTNode* root);


//二叉树的节点个数
int BinaryTreeSize(BTNode* root);

//二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root);

// ⼆叉树第k层结点个数
int BinaryTreeLeavelKSize(BTNode* root, int k);

//二叉树的深度
int BinaryTreeDepth(BTNode* root);

//二叉树查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTNDataType x);

// ⼆叉树销毁
void BinaryTreeDestory(BTNode** root);

//二叉树的层序遍历
void LevelOrder(BTNode* root);

//判断二叉树是否为完全二叉树
bool BinaryTreeComplete(BTNode* root);

BinaryTree.c源码

//BinaryTree.c文件中
#include "BinaryTree.h"

//前序遍历 根左右
void PerOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	printf("%d ", root->x);
	PerOrder(root->left);
	PerOrder(root->right);
}

//中序遍历 左根右
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	InOrder(root->left);
	printf("%d ", root->x);
	InOrder(root->right);
}

//前序遍历 左右根
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->x);
}

//二叉树的节点个数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

//二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

// ⼆叉树第k层结点个数
int BinaryTreeLeavelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return BinaryTreeLeavelKSize(root->left, k - 1) + BinaryTreeLeavelKSize(root->right, k - 1);
}

int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	//if (root->left == NULL && root->right == NULL)
	//{
	//	return 1;
	//}

	int numLeft = BinaryTreeDepth(root->left);
	int numRight = BinaryTreeDepth(root->right);

	return 1 + (numLeft > numRight ? numLeft : numRight);
}

//找到结点为x的值
BTNode* BinaryTreeFind(BTNode* root, BTNDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->x == x)
	{
		return root;
	}

	BTNode* retLeft = BinaryTreeFind(root->left, x);
	if (retLeft)
		return retLeft;

	BTNode* retRight = BinaryTreeFind(root->right, x);
	if (retRight)
		return retRight;

	return NULL;
}

//二叉树的销毁
void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}

	BTNode* leftTree = (*root)->left;
	BTNode* rightTree = (*root)->right;
	free(*root);
	*root = NULL;
	BinaryTreeDestory(&leftTree);
	BinaryTreeDestory(&rightTree);
}

void LevelOrder(BTNode* root)
{
	Queue pq;
	QueueInit(&pq);
	//将根结点放入队列中

	QueuePush(&pq, root);

	while (!QueueEmpty(&pq))
	{
		if (QueueFront(&pq) != NULL)
			printf("%d ", QueueFront(&pq)->x);
		else
			printf("NULL ");

		if (QueueFront(&pq) != NULL)
		{
			QueuePush(&pq, QueueFront(&pq)->left);
			QueuePush(&pq, QueueFront(&pq)->right);
		}

		QueuePop(&pq);
	}

	QueueDestory(&pq);
}

bool BinaryTreeComplete(BTNode* root)
{
	Queue pq;
	QueueInit(&pq);

	QueuePush(&pq, root);

	while (QueueFront(&pq)!=NULL)
	{
		QueuePush(&pq, QueueFront(&pq)->left);
		QueuePush(&pq, QueueFront(&pq)->right);

		QueuePop(&pq);
	}

	while (!QueueEmpty(&pq))
	{
		if (QueueFront(&pq) != NULL)
		{
			QueueDestory(&pq);
			return false;
		}
		QueuePop(&pq);
	}

	QueueDestory(&pq);
	return true;
}

2.2函数实现详解

2.2.1前中后序遍历

我们下面讲解前中后序遍历都通过下面该树来讲解
在这里插入图片描述

(只详细讲解前序遍历,其他遍历类似,只讲解代码)

1. 前序遍历 (Pre-order Traversal)

定义: 前序遍历按照 “根 -> 左 -> 右” 的顺序访问节点。

访问顺序:

  1. 访问根节点。
  2. 前序遍历左子树。
  3. 前序遍历右子树。

特点: 前序遍历首先访问当前节点,然后依次访问左子树和右子树。这种遍历方式可以用于表达式树的拷贝或克隆,因为它首先处理的是每个节点的值

动图讲解:

在这里插入图片描述

前序遍历 (Pre-order Traversal)

void PerOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	printf("%d ", root->x);
	PerOrder(root->left);
	PerOrder(root->right);
}

详细解析:

  • 功能: 前序遍历按照"根-左-右"的顺序访问节点。
  • 过程:
    1. 根节点: 首先访问当前节点,如果节点不为空,则打印节点的值 root->x
    2. 左子树: 递归调用 PerOrder(root->left) 访问左子树。
    3. 右子树: 递归调用 PerOrder(root->right) 访问右子树。

递归思路: 递归地访问左子树和右子树,直到访问到叶子节点为止。每次递归调用时,将当前节点的子节点作为新的根节点。

中序遍历 (In-order Traversal)

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	InOrder(root->left);
	printf("%d ", root->x);
	InOrder(root->right);
}

详细解析:

  • 功能: 中序遍历按照"左-根-右"的顺序访问节点。
  • 过程:
    1. 左子树: 递归调用 InOrder(root->left) 访问左子树。
    2. 根节点: 访问当前节点,打印节点的值 root->x
    3. 右子树: 递归调用 InOrder(root->right) 访问右子树。

用途: 在二叉搜索树中,中序遍历会按升序输出节点的值。

后序遍历 (Post-order Traversal)

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->x);
}

详细解析:

  • 功能: 后序遍历按照"左-右-根"的顺序访问节点。
  • 过程:
    1. 左子树: 递归调用 PostOrder(root->left) 访问左子树。
    2. 右子树: 递归调用 PostOrder(root->right) 访问右子树。
    3. 根节点: 访问当前节点,打印节点的值 root->x

用途: 通常用于删除或释放树中的节点,因为在访问根节点之前,确保了其子节点已经被处理。

2.2.2二叉树的其他方法实现

二叉树的节点个数 (BinaryTreeSize)

int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

详细解析:

  • 功能: 计算二叉树的总节点数。
  • 过程:
    1. 空节点: 如果当前节点为空,返回 0。
    2. 递归计数: 返回值为 1(当前节点)加上左子树和右子树的节点数总和。

递归思路: 每次调用都会返回当前节点加上左右子树的节点数,总体上遍历了整个树。

二叉树叶子结点个数 (BinaryTreeLeafSize)

int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

详细解析:

  • 功能: 计算二叉树中叶子节点的数量。叶子节点是没有子节点的节点。
  • 过程:
    1. 空节点: 如果当前节点为空,返回 0。
    2. 叶子节点: 如果节点的左右子树均为空,返回 1。
    3. 递归计数: 返回左子树和右子树的叶子节点数之和。

二叉树第 k 层结点个数 (BinaryTreeLeavelKSize)

int BinaryTreeLeavelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return BinaryTreeLeavelKSize(root->left, k - 1) + BinaryTreeLeavelKSize(root->right, k - 1);
}

详细解析:

  • 功能: 计算二叉树第 k 层的节点数。
  • 过程:
    1. 空节点: 如果当前节点为空,返回 0。
    2. 当前层: 如果 k 为 1,表示当前层即为第 k 层,返回 1。
    3. 递归计数: 递归调用函数,计算左右子树中第 k-1 层的节点数之和。

递归思路: 每递归一次,层数减一,直到 k 为 1 时,表示到达目标层。

二叉树的深度 (BinaryTreeDepth)

int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int numLeft = BinaryTreeDepth(root->left);
	int numRight = BinaryTreeDepth(root->right);

	return 1 + (numLeft > numRight ? numLeft : numRight);
}

详细解析:

  • 功能: 计算二叉树的深度(从根节点到最远叶子节点的最长路径)。
  • 过程:
    1. 空节点: 如果当前节点为空,返回 0。
    2. 递归计算: 递归地计算左子树和右子树的深度,取其中较大值加 1(当前节点深度)。

递归思路: 计算每个节点的深度时,考虑左右子树的最大深度,加上当前节点所在的层数。

查找值为 x 的节点 (BinaryTreeFind)

BTNode* BinaryTreeFind(BTNode* root, BTNDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->x == x)
	{
		return root;
	}

	BTNode* retLeft = BinaryTreeFind(root->left, x);
	if (retLeft)
		return retLeft;

	BTNode* retRight = BinaryTreeFind(root->right, x);
	if (retRight)
		return retRight;

	return NULL;
}

详细解析:

  • 功能: 查找二叉树中值为 x 的节点。
  • 过程:
    1. 空节点: 如果当前节点为空,返回 NULL
    2. 匹配节点: 如果当前节点的值为 x,返回当前节点。
    3. 递归查找: 先在左子树中查找,如果找到,返回该节点;否则在右子树中查找。

递归思路: 通过递归遍历树的每一个节点,查找指定值的节点。

二叉树的销毁 (BinaryTreeDestory)

void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}

	BTNode* leftTree = (*root)->left;
	BTNode* rightTree = (*root)->right;
	free(*root);
	*root = NULL;
	BinaryTreeDestory(&leftTree);
	BinaryTreeDestory(&rightTree);
}

详细解析:

  • 功能: 销毁二叉树,释放所有节点的内存。
  • 过程:
    1. 空节点: 如果当前节点为空,返回。
    2. 递归销毁: 递归地销毁左子树和右子树,然后释放当前节点的内存。

递归思路: 先销毁子节点,再销毁当前节点,确保不会丢失任何内存。

2.2.3二叉树的层序遍历和判断是否是完全二叉树

实现这两个方法,需要借助到前面我们所实现的队列的数据结构

Queue.h中需要更改的地方:

typedef struct BinaryTreeNode* QueueDataType;
//我们所需要存储的数据类型是二叉树的结点 所以将int更改为struct BinaryTreeNode*
//注:struct BinaryTreeNode* 中的struct的关键字一定要带着
typedef struct QueueNode
{
	QueueDataType  x;
	struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;
}Queue;

上面就是Queue.h所需更改的地方,其他的代码直接拷贝复制即可使用

层序遍历 (LevelOrder)

void LevelOrder(BTNode* root)
{
	Queue pq;
	QueueInit(&pq);
	QueuePush(&pq, root);

	while (!QueueEmpty(&pq))
	{
		if (QueueFront(&pq) != NULL)
			printf("%d ", QueueFront(&pq)->x);
		else
			printf("NULL ");

		if (QueueFront(&pq) != NULL)
		{
			QueuePush(&pq, QueueFront(&pq)->left);
			QueuePush(&pq, QueueFront(&pq)->right);
		}

		QueuePop(&pq);
	}

	QueueDestory(&pq);
}

详细解析:

  • 功能: 按层次从上到下、从左到右遍历二叉树。
  • 过程:
    1. 队列初始化: 使用队列来保存每层的节点。将根节点入队。
    2. 遍历: 当队列不为空时,取出队首节点并访问(打印)它的值。若该节点不为空,则将其左右子节点依次入队。
    3. 销毁队列: 最后销毁队列,释放内存。

队列的应用: 利用队列的 FIFO 特性实现层序遍历。

动图图解

在这里插入图片描述

判断是否为完全二叉树 (BinaryTreeComplete)

bool BinaryTreeComplete(BTNode* root)
{
	Queue pq;
	QueueInit(&pq);

	QueuePush(&pq, root);

	while (QueueFront(&pq) != NULL)
	{
		QueuePush(&pq, QueueFront(&pq)->left);
		QueuePush(&pq, QueueFront(&pq)->right);

		QueuePop(&pq);
	}

	while (!QueueEmpty(&pq))
	{
		if (QueueFront(&pq) != NULL)
		{
			QueueDestory(&pq);
			return false;
		}
		QueuePop(&pq);
	}

	QueueDestory(&pq);
	return true;
}

详细解析:

  • 功能: 判断一个二叉树是否为完全二叉树。
  • 完全二叉树定义: 除了最后一层外,每层的节点都是满的,并且最后一层的节点从左到右是连续的。
  • 过程:
    1. 队列初始化: 将根节点入队。
    2. 遍历队列: 对于每个节点,如果队列中的节点为非空,则将其左右子节点入队。直到遇到第一个空节点为止。
    3. 验证完全性: 遇到第一个空节点后,检查队列中是否还有非空节点。如果有,则该树不是完全二叉树;如果没有,则是完全二叉树。

关键点: 空节点后不应再出现非空节点,否则树不符合完全二叉树的定义。

🥇结语

在本篇文章中,我们深入探讨了链式二叉树这一重要的数据结构。我们介绍了它的基本概念和结构,讲解了如何创建和操作链式二叉树,并通过实际代码示例展示了其在C语言中的实现。链式二叉树因其灵活性和高效性,在处理许多实际问题时具有重要意义。希望通过本文的学习,您能够更好地理解链式二叉树的工作原理,并能在实际编程中有效地应用这一数据结构。随着对链式二叉树的掌握,您将在数据结构和算法的学习道路上迈出重要一步,为后续的更复杂的树结构和高级算法打下坚实的基础。感谢您阅读本篇文章,我们期待在下一篇文章中继续与您探讨更多有趣的编程知识。

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

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

相关文章

论文笔记:InternImage—基于可变形卷积的视觉大模型,超越ViT视觉大模型,COCO 新纪录 64.5 mAP!

文章信息 Title&#xff1a;InternImage: Exploring Large-Scale Vision Foundation Models with Deformable ConvolutionsPaper Link&#xff1a;https://arxiv.org/abs/2211.05778 Code Link&#xff1a;https://github.com/OpenGVLab/InternImage 写在前面 拿到文章之后先看…

科普文:微服务之Spring Cloud Alibaba消息队列组件RocketMQ如何保证发送消息不丢失

概叙 本文分析了 RocketMQ 同步发送、异步发送和单向发送三种方式的原理、优缺点以及使用场景&#xff0c;并且分析了每种方式涉及到的核心源码。 科普文&#xff1a;微服务之Spring Cloud Alibaba版本选择-CSDN博客 通过上文的介绍可以知道同步发送方式可以保证消息发送时不…

git分支介绍

git branch 查看当前分支情况 可以看见当前只有一个分支叫main&#xff0c;也就是默认分支&#xff0c;可以理解为树的主干&#xff0c;git早期版本中默认分支叫master 命令行创建一个新分支 git branch [分支名]在创建之后&#xff0c;如果需要切换到新分支需要git switc…

用VBA在Word文档中快速查找到黄色底纹内容

一、效果展示 二、代码 Sub 快速查找定位到黄色底纹内容()With Selection.Find.ClearFormatting.Wrap wdFindContinue.Font.Shading.BackgroundPatternColorIndex wdYellow.ExecuteEnd With End Sub

C++面向对象高级编程(I)侯捷 自我总结版

关键词&#xff1a; 类的防卫式声明&#xff0c;模版&#xff0c;内联函数&#xff0c;构造函数以及重载&#xff0c;const&#xff0c;pass by reference&#xff08;有&符号&#xff09;&#xff0c;friend&#xff0c;操作符重载&#xff0c;返回local object的不能retu…

【LightGlue】lightglue performance

【LightGlue】lightglue performance 1. 图表分析2. 数据点解释3. LightGlue的细节4. 结论 这张图表展示了不同特征匹配方法在图像对每秒处理速度和相对位姿精度&#xff08;Relative Pose Accuracy&#xff09;之间的关系。 1. 图表分析 X轴&#xff08;横轴&#xff09;&…

使用 abortNavigation 阻止导航

title: 使用 abortNavigation 阻止导航 date: 2024/8/3 updated: 2024/8/3 author: cmdragon excerpt: 摘要&#xff1a;在Nuxt3中&#xff0c;abortNavigation是一个辅助函数&#xff0c;用于路由中间件内阻止不符合条件的页面访问&#xff0c;实现权限控制、错误处理及动态…

3条职场情商法则,让你少走弯路

人生的幸福和工作息息相关&#xff0c;它占据了大量时间&#xff0c;而时间是人生最珍贵的资源。但当年轻人从校园走进职场时&#xff0c;却常常面临困境。因为职场和学校是完全不同的场所&#xff0c;游戏规则大相径庭。 人们会惊奇地发现&#xff0c;曾经的学霸可能在职场中…

Qt 5.14安装(配置MSVC 2017)

Qt 5.14安装&#xff08;配置MSVC 2017&#xff09; 记录一下自己安装配置Qt的步骤。 我需要安装Qt&#xff0c;并使用MSVC编译&#xff0c;所以才写了这篇文章。 一、环境 操作系统&#xff1a;windows 11 &#xff08;64位&#xff09; Qt&#xff1a;Qt 5.14.2 vs&…

Linux 命令,touch说明与使用

1&#xff1a;touch命令功用&#xff1a; 对一个或多个文件,将访问时间和修改时间以及日期进行更新&#xff0c;既在 Linux 和 Unix 系统中&#xff0c;改变文件的访问和修改时间&#xff0c;touch对于强制其他的命令以某一方式处理文件时是有用的。如make的操作 和某些find命令…

LED显示屏的秘密:揭秘模拟信号与模拟电路

在我们日常生活中&#xff0c;LED显示屏无处不在&#xff0c;从商场的广告牌到舞台的背景墙&#xff0c;它们用绚丽多彩的画面吸引着我们的眼球。但你是否好奇&#xff0c;这些神奇的屏幕背后&#xff0c;是如何处理和显示信息的呢&#xff1f;今天&#xff0c;就让我们一起揭开…

计算机毕业设计hadoop+hive+spark医院数据分析大屏 医疗数据分析 医疗可视化 医院大数据 医院爬虫 医疗爬虫 数据仓库 大数据毕业设计

绪论 研究背景和意义 近年来&#xff0c;随着第五次科技革命的到来&#xff0c;科学、信息技术等迅猛发展&#xff0c;医疗信息方面的数据激增&#xff0c;全国各大医院每日也产生大量的数据&#xff0c;包括门诊每日接诊数据、患者信息数据、医院资源消耗数据等。数据的高速产…

Radamsa:一款高性能通用模糊测试工具

关于Radamsa Radamsa是一款高性能的通用模糊测试工具&#xff0c;广大研究人员可以将其当作一个应用程序稳定性测试的测试用例生成工具。 工具运行机制 该工具使用简单&#xff0c;支持自定义脚本开发&#xff0c;可以用于测试程序对格式错误和潜在恶意输入的承受能力。它的工…

MapCrafter - 定制精美的地图海报! | 限时免费

MapCrafter: 打造个性化城市地图海报的终极工具&#xff01; 在您的 iPhone、iPad、Mac 或 VisionPro 上轻松制作美丽的城市地图海报&#xff0c;展示您的城市情感与创意。 https://apps.apple.com/cn/app/mapcrafter/id6557037905 为什么选择 MapCrafter&#xff1f; • 城市…

【中项】系统集成项目管理工程师-第9章 项目管理概论-9.7 项目管理原则

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

CTF-web基础 TCP/UDP协议

传输层协议由TCP/UDP协议组成&#xff0c;来控制信息的传输&#xff0c;二者有什么区别呢&#xff0c;TCP比较靠谱&#xff0c;但是UDP速度比较快一点。 TCP协议 Transmission Control protocol&#xff0c; 三次握手&#xff1a;先给服务器传输询问要发消息&#xff0c;然后…

Python语言编制批处理文件管理器

在软件开发和系统管理中&#xff0c;批处理文件&#xff08;.bat&#xff09;是一种常见且有用的工具。它们可以自动化重复性任务&#xff0c;简化复杂的操作流程。然而&#xff0c;随着批处理文件数量的增加&#xff0c;管理和执行这些文件可能变得麻烦。今天&#xff0c;我们…

uniapp HarmonyOS项目实战

1. uniapp HarmonyOS项目实战 Dcloud发布了uniapp兼容鸿蒙的文档&#xff1a;Uniapp开发鸿蒙应用 1.1. 说明 &#xff08;1&#xff09;鸿蒙开发只支持Vue3&#xff0c;不支持Vue2、不支持plus、但支持nvue &#xff08;2&#xff09;nvue编译到鸿蒙后非原生渲染&#xff0c;…

AUTOSAR实战教程 - 模式管理BswM与其他各模块的交互

近日驻厂某OEM,幸得大块的个人时间, 把BswM这一块的内容从ETAS/ISOLAR工具配置到代码实现做了一个全方位的CT. 2024,希望孜孜内卷的汽车人升职加薪! 博主近期写的一首小诗,也一并送给大家,懂的都懂: 在看不到阳光的冬天/ 我染了风寒/ 白天点灯/ 晚上吃药/ 躺在被窝里才敢…

2024上海初中生古诗文大会暑假备考:单选题真题和独家解析

今天是2024年8月3日&#xff0c;现在距离2024年初中生古诗文大会初选还有3个月&#xff08;11月3日正式开赛&#xff09;&#xff0c;我们继续来看10道选择题真题和详细解析。为帮助孩子自测和练习&#xff0c;题目的答案和解析统一附后。 本专题持续分享&#xff0c;欢迎到我…