数据结构【链试结构二叉树】

news2024/11/15 11:57:19

 


🌟个人主页:落叶

目录

 ​编辑

实现链式结构⼆叉树

前中后序遍历:

遍历规则

代码实现

前序遍历:

中序遍历:

后序遍历:

图解遍历:

函数递归栈帧图:

结点个数以及高度等

【⼆叉树】结点个数

【二叉树】叶子节点个数

【二叉树】第k层节点个数

【二叉树】的深度/⾼度

【二叉树】查找值为x的结点 

【二叉树】销毁

层序遍历

判断是否为完全二叉树


🔥摘要:设⼆叉树的根结点所在层数 为1,层序遍历就是从所在⼆叉树的根结点出发,⾸先访问第⼀层的树根结点,然后从左到右访问第2 层上的结点,接着是第三层的结点,以此类推,⾃上⽽下,⾃左⾄右逐层访问树的结点的过程就是层 序遍历。根结点的左⼦树和右⼦树分别⼜是由⼦树结点、⼦树结点的左⼦树、⼦树结点的右⼦树组成的,因此 ⼆叉树定义是递归式的,后序链式⼆叉树的操作中基本都是按照该概念实现的。回顾⼆叉树的概念,⼆叉树分为空树和⾮空⼆叉树,⾮空⼆叉树由根结点、根结点的左⼦树、根结点 的右⼦树组成的。根结点、左⼦树、右⼦树。

实现链式结构⼆叉树

⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。通常的⽅法是链表中每个结点由三个域组 成,数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址, 其结构如下:

创建二叉树数据:

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

typedef int data;
typedef struct Tree
{
	int arr;    //数值
	struct Tree* zuo;//左孩子
	struct Tree* you;//右孩子
}BT;

⼆叉树的创建⽅式⽐较复杂,为了更好的步⼊到⼆叉树内容中,我们先⼿动创建⼀棵链式⼆叉树

我们进行连接后就成下面这个二叉树


当然我们也可以这样看

//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);
	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

}



int main()
{
	p();
	return 0;
}

回顾⼆叉树的概念,⼆叉树分为空树和⾮空⼆叉树,⾮空⼆叉树由根结点、根结点的左⼦树、根结点 的右⼦树组成的

根结点的左⼦树和右⼦树分别⼜是由⼦树结点、⼦树结点的左⼦树、⼦树结点的右⼦树组成的,因此 ⼆叉树定义是递归式的,后序链式⼆叉树的操作中基本都是按照该概念实现的。

前中后序遍历:

⼆叉树的操作离不开树的遍历,我们先来看看⼆叉树的遍历有哪些⽅式

遍历规则

按照规则,⼆叉树的遍历有:前序/中序/后序的递归结构遍历:

(1)前序遍历(PreorderTraversal亦称先序遍历):访问根结点的操作发⽣在遍历其左右⼦树之前

访问顺序为:根结点、左⼦树、右⼦树

(2)中序遍历(InorderTraversal):访问根结点的操作发⽣在遍历其左右⼦树之中(间)

访问顺序为:左⼦树、根结点、右⼦树

(3)后序遍历(PostorderTraversal):访问根结点的操作发⽣在遍历其左右⼦树之后

访问顺序为:左⼦树、右⼦树、根结点

代码实现
前序遍历:

访问顺序为:根结点、左⼦树、右⼦树

//前序遍历-(根-左-右)
void qian(BT* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("%d ", root->arr);
	//左子树
	qian(root->zuo);
	//右子树
	qian(root->you);
}



结果:

//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;
	
	qian(n1);
	printf("\n");




}



int main()
{
	p();
	return 0;
}

中序遍历:

访问顺序为:左⼦树、根结点、右⼦树

//中序遍历-(左-根-右)
void zho(BT* root)
{
	if (root == NULL)
	{
		return;
	}
	//左子树
	zho(root->zuo);
	printf("%d ", root->arr);
	//右子树
	zho(root->you);
}



结果:

//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);
	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

	/*qian(n1);
	printf("\n");*/

	zho(n1);
	printf("\n");

}



int main()
{
	p();
	return 0;
}

后序遍历:

访问顺序为:左⼦树、右⼦树、根结点

//后序遍历
void ho(BT* root)
{
	if (root == NULL)
	{
		return;
	}
	//左子树
	ho(root->zuo);
	//右子树
	ho(root->you);
	printf("%d ", root->arr);
}



结果:

//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;
	
	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	ho(n1);

}



int main()
{
	p();
	return 0;
}

图解遍历:

以前序遍历为例:


函数递归栈帧图:


前序遍历结果:123456

中序遍历结果:321546

后序遍历结果:315641


结点个数以及高度等
【⼆叉树】结点个数

// ⼆叉树结点个数 
int BinaryTreeSize(BT* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//                左子树                     右子树
	return 1+ BinaryTreeSize(root->zuo)+ BinaryTreeSize(root->you);
}



结果:

//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	//ho(n1);
	// ⼆叉树结点个数 
	printf("size:%d \n", BinaryTreeSize(n1));


}



int main()
{
	p();
	return 0;
}

【二叉树】叶子节点个数

// ⼆叉树叶⼦结点个数 
int BinaryTreeLeafSize(BT* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//左子树和右子树都等于空,就是叶子节点
	if (BinaryTreeLeafSize(root->zuo) == NULL && BinaryTreeLeafSize(root->you) == NULL)
	{
		return 1;
	}
	return BinaryTreeLeafSize(root->zuo) + BinaryTreeLeafSize(root->you);
}



结果:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);


	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

	
	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	//ho(n1);
	// ⼆叉树结点个数 
	//printf("size:%d \n", BinaryTreeSize(n1));

	//叶子节点个数
	printf("叶子节点:%d\n", BinaryTreeLeafSize(n1));



}



int main()
{
	p();
	return 0;
}

【二叉树】第k层节点个数

// ⼆叉树第k层结点个数 
int BinaryTreeLevelKSize(BT* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	//k等于1了就返回1
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLevelKSize(root->zuo, k - 1) + BinaryTreeLevelKSize(root->you, k - 1);
}



结果:

这里加了2个节点5和6,就和上面那张图一样了。

#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;
	
	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	//ho(n1);
	// ⼆叉树结点个数 
	//printf("size:%d \n", BinaryTreeSize(n1));

	// 
	叶子节点个数
	//printf("叶子节点:%d\n", BinaryTreeLeafSize(n1));
	//k层节点个数
	printf("k: %d \n", BinaryTreeLevelKSize(n1, 3));


}



int main()
{
	p();
	return 0;
}

【二叉树】的深度/⾼度

//⼆叉树的深度/⾼度
int BinaryTreeDepth(BT* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//遍历左子树,把值给zuo
	int zuo = BinaryTreeDepth(root->zuo);
	//遍历右子树,把值给you
	int you = BinaryTreeDepth(root->you);
	//进行判断
	return zuo > you ? zuo + 1:you + 1;
}



结果:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

	
	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	//ho(n1);
	// ⼆叉树结点个数 
	//printf("size:%d \n", BinaryTreeSize(n1));

	// 
	叶子节点个数
	//printf("叶子节点:%d\n", BinaryTreeLeafSize(n1));
	k层节点个数
	//printf("k: %d \n", BinaryTreeLevelKSize(n1, 3));

	//⼆叉树的深度/⾼度
	printf("高度:%d \n", BinaryTreeDepth(n1));

}



int main()
{
	p();
	return 0;
}

【二叉树】查找值为x的结点 

// ⼆叉树查找值为x的结点 
BT* BinaryTreeFind(BT* root, data x)
{
	if (root == NULL)
	{
		return NULL;
	}
	//等于x,返回当前节点
	if (root->arr == x)
	{
		return root;
	}
	//zuo接收节点
	BT* zuo = BinaryTreeFind(root->zuo, x);
	if (zuo)
	{
		//返回节点
		return zuo;
	}
	//you接收节点
	BT* you = BinaryTreeFind(root->you, x);
	if (you)
	{
		//返回节点
		return you;
	}
}


左子树找不到,就找右子树


结果:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
//申请空间
BT* koj(data x)
{
	//申请节点
	BT* tab = (BT*)malloc(sizeof(BT));
	if (tab == NULL)
	{
		perror("malloic");
		exit(1);
	}
	tab->arr = x;
	tab->zuo= tab->you = NULL;

	return tab;
}
void p()
{
	//创建节点
	BT* n1 = koj(1);
	BT* n2 = koj(2);
	BT* n3 = koj(3);
	BT* n4 = koj(4);

	//BT* n5 = koj(5);
	//BT* n6 = koj(6);
	//进行连接
	n1->zuo = n2;
	n1->you = n3;
	n2->zuo = n4;

	//n2->you = n5;
	//n3->zuo = n6;
	
	/*qian(n1);
	printf("\n");*/

	/*zho(n1);
	printf("\n");*/

	//ho(n1);
	// ⼆叉树结点个数 
	//printf("size:%d \n", BinaryTreeSize(n1));

	// 
	叶子节点个数
	//printf("叶子节点:%d\n", BinaryTreeLeafSize(n1));
	k层节点个数
	//printf("k: %d \n", BinaryTreeLevelKSize(n1, 3));

	⼆叉树的深度/⾼度
	//printf("高度:%d \n", BinaryTreeDepth(n1));

	// ⼆叉树查找值为x的结点 
	BT* tab = BinaryTreeFind(n1, 4);
	printf("%s\n", tab == NULL ? "没找到" : "找到了");


}



int main()
{
	p();
	return 0;
}

【二叉树】销毁



// ⼆叉树销毁
void BinaryTreeDestory(BT** root)
{
	if (*root == NULL)
	{
		return;
	}
	//二级指针,需要传一级指针地址
	BinaryTreeDestory(&(*root)->zuo);
	BinaryTreeDestory(&(*root)->you);
	//释放空间
	free(*root);
	*root = NULL;
}

图解析:


结果:

我们可以看到全部销毁了。


层序遍历

除了先序遍历、中序遍历、后序遍历外,还可以对⼆叉树进⾏层序遍历。设⼆叉树的根结点所在层数 为1,层序遍历就是从所在⼆叉树的根结点出发,⾸先访问第⼀层的树根结点,然后从左到右访问第2 层上的结点,接着是第三层的结点,以此类推,⾃上⽽下,⾃左⾄右逐层访问树的结点的过程就是层 序遍历

实现层序遍历需要额外借助数据结构:队列


创建队列,初始化,把根节点入队列

循环队列不为空,取队头打印,出队头。

然后判断左子树和右子树,是不是空,不是空就入队列。

销毁队列。

//层序遍历
//借助数据结构--队列
void LevelOrder(BT* root)
{
	Queue add;
	//初始化
	Queuecsh(&add);
	//入数据
	Queue_ruwei(&add, root);

	while (!buer(&add))
	{
		//取队头-打印
		BT* tab = qto(&add);
		printf("%d ", tab->arr);
		//出队
		Queue_chu(&add);
		//判断是不是空, 队头节点的左右孩子入,队列
		if (tab->zuo)
		{
			Queue_ruwei(&add, tab->zuo);
		}
		if (tab->you)
		{
			Queue_ruwei(&add, tab->you);
		}
	}

	//队列销毁
	Queuexiaoh(&add);
}

结果:


判断是否为完全二叉树


注意:

如果是完全二叉树,跳出循环之后队列里都是NULL。

如果不是完全二叉树,跳出循环之后队列里,还有非空节点。

思路:

创建一个队列,把根节点入队列,循环队列里不为空。

取队头节点,然后出队,判断这个节点是不是空,是空跳出循环。

不是空,左子树和右子树入队列。

是完全二叉树的话剩下的都是空,

循环取出队头数据,出队,进行判断,不等于空的话还有非空节点,那就是不完全二叉树了,返回false。

最后循环都为空,是完全二叉树,返回true。


bool pdercs(BT* root)
{
	Queue add;
	//队列初始化
	Queuecsh(&add);
	//入队列
	Queue_ruwei(&add, root);
	while (!buer(&add))
	{
		//取队头数据
		BT* tab =  qto(&add);
		//出队
		Queue_chu(&add);
		if (tab == NULL)
		{
			//等于空结束循环
			break;
		}//不为空让左右子树入队列

		//左子树_入队列
		Queue_ruwei(&add, tab->zuo);
		//右子树_入队列
		Queue_ruwei(&add, tab->you);
	}
	//循环判断队列,有一个数值不是完全二叉树,都是NULL就是完全二叉树
	while (!buer(&add))
	{
		//取队头
		BT* app = qto(&add);
		//出队
		Queue_chu(&add);
		//判断如果还有非空节点,返回false
		if (app != NULL)
		{
			Queuexiaoh(&add);
			return false;
		}
	}//循环完,说明队列里都是NULL,是完全二叉树,返回true

	//队列销毁
	Queuexiaoh(&add);
	return true;
}

结果:

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

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

相关文章

【生日视频制作】教师节中秋节国庆节奔驰大G汽车车身AE模板修改文字软件生成器教程特效素材【AE模板】

奔驰大G汽车身生日视频制作教程AE模板修改字软件生成器素材 怎么如何做的【生日视频制作】教师节中秋节国庆节奔驰大G汽车车身AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤&#xff1a; 安装AE软件下载AE模板把AE模板导入AE软件修改图片或文字渲染出视频…

iOS工程:获取手机相册权限,iOS原生系统弹窗, Privacy隐私政策选择,如何添加系统弹出并修改描述文字

【iOS工程】获取手机相册权限&#xff0c;iOS原生系统弹窗, Privacy隐私政策选择&#xff0c;如何添加系统弹出并修改描述文字 设备/引擎&#xff1a;Mac&#xff08;11.6&#xff09;/Mac Mini 开发工具&#xff1a;Xcode&#xff08;15.0.1&#xff09; 开发需求&#xff…

maven Tomcat插件安装 运行web项目 (3)

1.maven工程目录结构 main是用来写我们程序 test是用来测试 java是源程序 resource是配置 maven项目构建命令 2.配置maven 创建Maven工程 这里的项目名称可以随便取 进来后改成自己想要的jdk

天津市2024年成人高考报名须知

&#x1f6a7;天津市2024年成人高考报名须知 &#x1f32b;2024年天津市成人高校招生考试报名。符合天津市报名条件的在职从人员和社会其他人员&#xff0c;可报名参加全国各类成人高等学校招生统一考试。考生须在规定时间完成报名&#xff0c;逾期不再补报。 &#x1f32b;网上…

微服务事务管理

1.分布式事务问题 1.1.本地事务 本地事务&#xff0c;也就是传统的单机事务&#xff0c;在传统数据库事务中&#xff0c;必须要满⾜四个原则&#xff1a; 1.2.分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产⽣的事务&#xff0c;例…

使用itextpdf5.x将网页转为PDF,并添页眉页脚页码

一、用到的Maven依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency><!-- 中文字体支持 --><dependency><groupId>com.itextpdf…

Gameplay Ability System(通过表配置不同等级的伤害)

一、创建配置表 1、创建Excel表格&#xff0c;输入数据&#xff0c;表示1级的普攻伤害为5&#xff1b;2级的普攻伤害为15。 2、另存为.csv格式文件。 3、当然也可以通过记事本直接写成下图这样。 二、导入UE5处理 1、导入为CurveTable的稳定格式&#xff0c;命名为CT_MeleeA…

探索厦门凯酷全科技有限公司抖音小店的实用魅力

在数字化浪潮汹涌的今天&#xff0c;电商平台如雨后春笋般涌现&#xff0c;而抖音作为短视频与电商融合的佼佼者&#xff0c;更是为众多企业开辟了新的营销与销售渠道。厦门凯酷全科技有限公司&#xff0c;作为这股潮流中的一股清流&#xff0c;凭借其独特的产品定位与创新的营…

【网络】传输层协议——UDP协议

1.传输层协议 首先我们要明白&#xff0c;进入传输层&#xff0c;也就进入了操作系统内核。 因为应用层下面这几个就是操作系统内部 我们学传输层及其以下几层&#xff0c;也就是在学操作系统内核的网络模块。 1.1.传输层协议 传输层能够实现端到端的连接。比如说我们用QQ与…

嵌入式开发实训室解决方案

随着物联网、智能制造、汽车电子等技术的飞速发展&#xff0c;嵌入式系统作为这些领域的核心技术之一&#xff0c;其重要性日益凸显。为了满足职业院对嵌入式开发人才的需求&#xff0c;构建一个高效、全面的嵌入式开发实训室显得尤为重要。本文旨在提出一套综合性的嵌入式开发…

监控软件可以看到员工在干什么吗?逆天功能!

企业对于工作效率和信息安全重视程度的不断提升&#xff0c;监控软件作为管理工具之一&#xff0c;逐渐在各大公司中普及开来。 这些软件旨在通过监控员工电脑活动、网络通信、甚至物理环境等&#xff0c;来帮助管理者更好地了解员工工作状态&#xff0c;防止数据泄露&#xf…

JVM系列--运行时数据区

Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。《Java虚拟机规范》中规定了每一部分的作用。 1 程序计数器 程序计数器&#xff08;Program Counter Register&#xff09;也叫PC寄存器&#xff0c;每个线程会通过程序计数器记录当前要执行的…

基于单片机的教室人数自动统计系统设计

摘 要&#xff1a; 以单片机 AT89C51 为核心&#xff0c;采用光电感应器和单片机系统的技术测量控制装置&#xff0c;同时利用红外装置采集信息&#xff0c;并将信号进行放大形成对应的高电平信号通过LED 显示反馈人数&#xff0c;从而达到管理的目的。文中对基于单片机的教室人…

【SQL】指定日期的产品价格

目录 题目 分析 代码 题目 产品数据表: Products ------------------------ | Column Name | Type | ------------------------ | product_id | int | | new_price | int | | change_date | date | ------------------------ (product_id, chang…

基于cubemx的STM32的freertos的串口通信

1、任务描述 使用freertos系统实现电脑调试助手和正点原子开发板STM32F103ZET6的串口通信。 2、cubemx设置 3、程序代码 &#xff08;1&#xff09;添加usart1.c #include "usart1.h"#include "usart.h"/**********重定义函数**********/struct __FILE …

Chat App 项目之解析(八)

Chat App 项目介绍与解析&#xff08;一&#xff09;-CSDN博客文章浏览阅读340次&#xff0c;点赞7次&#xff0c;收藏3次。Chat App 是一个实时聊天应用程序&#xff0c;旨在为用户提供一个简单、直观的聊天平台。该应用程序不仅支持普通用户的注册和登录&#xff0c;还提供了…

ArcGIS高/低聚类(Getis-Ord General G)——探究人口空间格局的20年变迁

先了解什么是高/低聚类&#xff1f; 高/低聚类 (Getis-Ord General G) 统计是一种用于检测空间数据中是否存在高值或低值聚类的统计方法&#xff0c;这种方法可以帮助我们理解数据点在空间上是否呈现某种聚集模式。 白话版&#xff1a;一句话就是判断数据在空间上有没有聚集。…

芯片后端之 PT 使用 report_timing 产生报告 之 -include_hierarchical_pins 选项

今天,我们再学习一点点 后仿真相关技能。 那就是,了解 report_timing 中的 -include_hierarchical_pins 选项。 如果我们仅仅使用如下命令,执行后会发现: pt_shell> report_timing -from FF1/CK -to FF2/d -delay_type max 我们使用命令 report_timing 报出的如上路…

基于Java语言的能源管理系统-水-电-气-热-油-数据采集系统源码

基于Java语言的能源管理系统-水电气热油数据采集系统源码 介绍 能源管理系统能源管理能源管理平台能源管理系统&#xff08;EMS&#xff09;能源监测能源管控能源系统能源监控能源预测&#xff0c;适用于高能耗企业能源企业 软件架构 软件功能 数据大屏 使用说明 参与贡献 …

【计算机三级-数据库技术】操作题大题(第八套)

第46题 &#xff08;1&#xff09; 1 (2) create table ( a1 int, a6 int, a10 int, Primary Key(a1, a6), Constraint fk_PerOrders Foreign Key (a1) References T1(a1), Constraint fk_PerOrders Foreign Key (a6) References T3(a6) ) 第47题 答案&#xff1a; [1]Pro…