当前位置: 首页 > news >正文

数据结构——二叉树——堆(1)

今天,我们来写一篇关于数据结构的二叉树的知识。

在学习真正的二叉树之前,我们必不可少的先了解一下二叉树的相关概念。

一:树的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的
 

注意:树形结构中,子树之间不能有交集,否则就不是树形结构

除了根结点外,每个结点有且仅有一个父结点

一颗N节点的树又N-1条边
 

下面我们来具体给出树的相关名词:

节点的度一个节点含有的子树的个数称为该节点的度; 如上图:A的为6

叶节点或终端节点度为0的节点称为叶节点; 如上图:B、C、H、I...等节点为叶节点

非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G...等节点为分支节点

双亲节点或父节点若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点

孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点

兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点树的度:

一棵树中,最大的节点的度称为树的度; 如上图:树的度为6

节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推

树的高度或深度树中节点的最大层次; 如上图:树的高度为4

堂兄弟节点:双亲在同一层的节点互为堂兄弟;如上图:H、I互为兄弟节点

节点的祖先从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

森林由m(m>0)棵互不相交的树的集合称为森林

标注:红色的为常用的,橙色为概念

有了上面的铺垫后,我们来认识一下二叉树:

二叉树

图:

二叉树组成: 

由三部分:根,左子树(左孩子),右子树(右孩子)

从上面,我们知道:

1.二叉树不存在度大于2的结点
2.二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

3. 存在情况:

接下来,我们认识

特殊的二叉树:

1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k-1 ,则它就是满二叉树。

2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树

 证明:满二叉树中高度为h的有多少个结点?

完全二叉树:前h-1都是满的
最后一层要求从左到右是连续的

高度为h的完全二叉数,节点数量的范围是[2^(h-1),2^h-1]

由上面知道满二叉树为2^h-1.

根据完全二叉树的定义

2^(h-1)-1----不算最后一层的。然后再算最后一层:2^(h-1)-1+1==2^(h-1)

所以,它的范围:[2^(h-1),2^h-1]。

此外,对任何一颗二叉树,如果度为0的叶结点个数为n0,度为2的分支节点为2 ,则由n0=n2+1.

结论:度为0的永远比度为2的多1。

二叉树的存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,

我们知道:顺序表是都一样的,实际上就是数组嘛
而链表不一样,我们通常用箭头那些是想象出来的,实际上并没有箭头的。

同样,二叉树也是:

逻辑结构  想象出来的

物理结构  实实在在内存中是如何存储的

反向过来,你把这棵树的一层一层的值依次往数组里面存储

如下图:

逻辑结构:(想象成这样)

物理结构:(实际就是数组) 

  

另外,我们平时画图的时候,很麻烦画出第一张图那么标准,其实,我们也是可以画出这样子

简便:

 通过观察上面得出的规律:

表示二叉树的值在数组位置中的父子下标关系

parent=(child-1)/2

leftchlid=parent*2+1
rightchlid=parent*2+2

注意,这里必须是从0开始,不然就乱了

有人会问了,能不能在完全二叉树那里使用呢?


这里用数组存储完全二叉数,有局限不适合。

因为浪费很多空间,数组存储表示二叉树只适合完全二叉树。

好了,有了上面的铺垫后,现在让我们来实现一下堆。

概念:

什么是堆呢?

我们将堆分为大堆和小堆

小堆

大堆:

 

在写堆时,底层代码实际就是数组
注意:堆不是排序,堆只规定父亲的大小,并没有规定它的左右孩子的大小

插入时,可能会影响部分祖先。
实际控制的是数组,写的时候把它想象成树

一:定义结构体

typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

1.需要一个数组

2.要算出数组的大小

3.最大容量

二:初始化部分

void HeapInit(HP* php)
{assert(php);php->a = (HPDataType*)malloc(sizeof(HPDataType)*4);if (php->a == NULL){perror("malloc fail");return;}php->size = 0;php->capacity = 4;
}

这里初始化跟之前的都差不多。

1.创建数组,用malloc

2.初始化size为0;

3.因为上面创建了数组:4个位置,所以初始化时的最大容量为4。

三:销毁部分

void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->capacity = php->size = 0;
}

1.置空,置零就可以了。

四:Push部分

首先,我们得思考一下,堆咋push的。

由于本质上是数组,所以我们push在数组的最后那里插。

假如在下面数组push一个数字60.

因此我们会写成这样一个代码:

void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * php->capacity*2);if (tmp == NULL){perror("realloc fail");return;}php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;php->size++;调整部分下面有讲AdjustUp(php->a, php->size - 1);
}

但是呢,如果是像上面一样push了一个数字的话,堆就乱了:

变成了

 面对这种问题,我们又该怎么办呢?

这里我们使用一种叫向上调整法解决这种问题:

我们以大堆来举例子:

我们发现上面是不是将30和60的位置交换了,就可以重新变成大堆了?

那么,我们又是怎么变成这一步的呢?

不能发现,你看

1.将分为左孩子和右孩子和根三部分。

2.比较左孩子和右孩子,拿出大的孩子,再跟根比较。

3.如果大的孩子的数字大于根,就交换。反之不换。

对上述做法叫做向上调整法。

对此我们写一个函数:

向上调整部分

void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;//while (parent >= 0)while(child > 0){if (a[child] > a[parent]){交换Swap(&a[child], &a[parent]);更新child = parent;parent = (child - 1) / 2;}else{break;}}
}

 解读:

除了child这个位置,前面数据构成堆

1.我们是不是得找到父亲结点。上面我们已经给出了父亲与孩子之间的公式变换了

2.由于交换这个代码内容在后面也是常用到的,所以我们单独封装一个函数

交换部分

void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType x = *p1;*p1 = *p2;*p2 = x;
}

3.这样容易忽略的问题是:

while的条件:弄成   while(child > 0)   而不要弄成while (parent >= 0)

这里看似都没有问题运行时,但是会不好。

parent >= 0,意味着parent<0才会中止,但是,parent会小于0吗?不会,因为这里最差的情况就是孩子等于0.

parent = (child - 1) / 2;即就是-1/2,按理是0.5,但是这里是整形,所以还是0,还是会进入循环。

但是呢?这个程序不会死循环,parent=0时,进入循环,但是它不满足if (a[child] > a[parent])条件,所以还是会到达break。

所以能正常跑,但是不好,最好用child>0.

删除部分

void HeapPop(HP* php)
{assert(php);后面讲到assert(!HeapEmpty(php));// 删除数据Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}

堆的删除部分,有人可能会想直接这样删

但是,接下来的堆就会变成这样:

直接挪动删除 :

1.效率低下。

2.父子兄弟关系全乱了。

 那么,我们想到用间接的方法来解决这种问题:

1.我们先把第一个和最后一个交换。

2.删除最后一个。

3.接着向下调整法。

1)什么是向下调整法,即从上面往下调

1.找到孩子中大的数字,与父亲比较,孩子大的就交换。反之不交换

向下调整部分

void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){// 选出左右孩子中大的那一个if (child + 1 < n && a[child+1] > a[child]){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

 1.这里采用的是假设左孩子大,然后再循环里面再弄个if语句,如果右孩子大的话,就交换变成右孩子。(因为左右孩子再邻位,相差1)

2.接着再比较父亲结点,与大的孩子,大就交换,再更新父亲结点和孩子结点。反之就break,跳出循环。

返回顶位置

HPDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}

判断空

bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}

返回大小

int HeapSize(HP* php)
{assert(php);return php->size;
}

好了,最后

附上总代码

Heap.h部分

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int HPTypeData;
typedef struct Heap
{HPTypeData* a;int size;int capacity;}Heap;void HPInit(Heap* php);
void HPDestory(Heap* php);
void HPPush(Heap* php, HPTypeData x);
void HPPop(Heap* php);
HPTypeData HPtop(Heap* php);
bool HPEmpty(Heap* php);
int HPSize(Heap* php);

Heap.c部分

#define _CRT_SECURE_NO_WARNINGS 1
#include "Heap.h"void HPInit(Heap* php)
{assert(php);php->a =(HPTypeData*)malloc(sizeof(HPTypeData)*4);if (php->a == NULL){perror("malloc fail");return;}php->capacity = 4;php->size = 0;
}
void HPDestory(Heap* php)
{assert(php);free(php->a);php->a = NULL;php->size = 0;php->capacity = 0;
}void Swap(HPTypeData* p1,HPTypeData* p2)
{HPTypeData temp = *p1;*p1 = *p2;*p2 = temp;
}
void Adjustup(HPTypeData* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent= (child - 1) / 2;}else{break;}}
}
void HPPush(Heap* php, HPTypeData x)
{assert(php);if (php->a == php->capacity){HPTypeData* temp = (HPTypeData*)realloc(php->a, sizeof(HPTypeData) * php->capacity * 2);if (temp == NULL){perror("realloc fail");return;}php->a = temp;php->capacity *= 2;}php->a[php->size] = x;php->size++;//Adjustup(php->a,php->a[php->size-1]);Adjustup(php->a,php->size-1);}Adjustdown(HPTypeData* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child + 1] > a[child]){child++;}if (a[child] > a[parent]){Swap(&a[parent],&a[child]);parent = child;child= parent * 2 + 1;}else{break;}}
}
void HPPop(Heap* php)
{assert(php);assert(!HPEmpty(php));Swap(&php->a[0], &php->a[php->size - 1]);php->size--;Adjustdown(php->a, php->size, 0);
}
HPTypeData HPtop(Heap* php)
{assert(php);return php->a[0];
}
bool HPEmpty(Heap* php)
{assert(php);return php->size == 0;
}
int HPSize(Heap* php)
{assert(php);return php->size;
}

test.c部分

#define _CRT_SECURE_NO_WARNINGS 1
#include "Heap.h"//int main()
//{
//	HP hp;
//	HeapInit(&hp);
//	HeapPush(&hp, 4);
//	HeapPush(&hp, 18);
//	HeapPush(&hp, 42);
//	HeapPush(&hp, 12);
//	HeapPush(&hp, 21);
//	HeapPush(&hp, 3);
//	HeapPush(&hp, 5);
//	HeapPush(&hp, 5);
//	HeapPush(&hp, 50);
//	HeapPush(&hp, 5);
//	HeapPush(&hp, 5);
//	HeapPush(&hp, 15);
//	HeapPush(&hp, 5);
//	HeapPush(&hp, 45);
//	HeapPush(&hp, 5);
//
//	int k = 0;
//	scanf("%d", &k);
//	while (!HeapEmpty(&hp) && k--)
//	{
//		printf("%d ", HeapTop(&hp));
//		HeapPop(&hp);
//	}
//	printf("\n");
//
//	return 0;
//}// 排升序 -- 建大堆
void HeapSort(int* a, int n)
{// 建堆 -- 向上调整建堆for (int i = 1; i < n; ++i){AdjustUp(a, i);}// 自己先实现}int main()
{int a[10] = { 2, 1, 5, 7, 6, 8, 0, 9, 4, 3}; // 对数组排序HeapSort(a, 10);return 0;
}

最后,到了本次鸡汤部分:

小小的人,有大大的梦想!干!

相关文章:

数据结构——二叉树——堆(1)

今天&#xff0c;我们来写一篇关于数据结构的二叉树的知识。 在学习真正的二叉树之前&#xff0c;我们必不可少的先了解一下二叉树的相关概念。 一&#xff1a;树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层…...

window保存好看的桌面壁纸

1、按下【WINR】快捷键调出“运行”窗口&#xff0c;输入以下命令后回车。 %localappdata%\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets 2、依次点击【查看】【显示】&#xff0c;勾选【隐藏的项目】&#xff0c;然后按【CtrlA】全部…...

docker安装Redis:docker离线安装Redis、docker在线安装Redis、Redis镜像下载、Redis配置、Redis命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull redis:7.4.0 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜像…...

98.1 AI量化开发:长文本AI金融智能体(Qwen-Long)对金融研报大批量处理与智能分析的实战应用

目录 0. 承前1. 简介1.1 通义千问(Qwen-Long)的长文本处理能力 2. 基础功能实现2.1 文件上传2.2 单文件分析2.3 多文件分析 3. 汇总代码&运行3.1 封装的工具函数3.2 主要功能特点3.3 使用示例3.4 首次运行3.5 运行结果展示 4. 注意事项4.1 文件要求4.2 错误处理机制4.3 最佳…...

【自然语言处理(NLP)】长短期记忆网络(Long - Short Term Memory,LSTM)原理和代码实现(从零实现、Pytorch实现)

文章目录 介绍长短期记忆网络&#xff08;Long - Short Term Memory&#xff0c;LSTM&#xff09;结构原理候选记忆元符号含义公式含义 记忆元符号含义公式含义 隐状态符号含义公式含义 特点应用实现 LSTMpytorch实现 个人主页&#xff1a;道友老李 欢迎加入社区&#xff1a;道…...

八股学习 微服务篇

微服务篇 常见面试内容Spring Cloud 常见组件注册中心Ribbon负载均衡策略服务雪崩 常见面试内容 Spring Cloud 常见组件 Spring Cloud有5个常见组件&#xff1a; Eureka/Nacos:注册中心&#xff1b;Ribbon:负载均衡&#xff1b;Feign:远程调用&#xff1b;Hystrix/Sentinel:服…...

TCP协议:互联网数据传输的守护者

在互联网的浩瀚海洋中&#xff0c;数据如同涓涓细流&#xff0c;无时无刻不在流动。而这些数据的稳定、可靠传输&#xff0c;离不开一个重要的协议——TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;。TCP协议作为互联网协议族中的核心成员…...

协助工具-任意门导航

任意门导航网址&#xff1a;随意门导航-最全的实用导航网站,好用简洁宝藏网址神器...

【MCAL实战】MCU模块配置实践

目录 前言 正文 1.硬件分析 1.1 MCU系统模式分析 1.2MCU晶振使用分析 2.MCU通用配置 2.1 McuGeneralConfiguration 2.2 McuModuleConfiguration 2.3 McuResetSettingConf 2.4 McuTrapSettingConf 2.4 其他 3.MCU模式配置 3.1 McuModeSettingConf_0 3.2 McuModeSe…...

OpenAI 发布首个 AI 智能体

OpenAI 发布首个 AI 智能体 当地时间 1 月 23 日&#xff0c;OpenAI 发布了首个 AI 智能体 Operator124。以下是关于它的详细介绍2&#xff1a; 功能用途 操作网页&#xff1a;可模拟人类操作网页浏览器&#xff0c;能进行点击、滚动、输入等操作&#xff0c;例如在 OpenTable…...

【Python】导入类

随着不断给类添加功能&#xff0c;文件可能变得很长&#xff0c;即便妥善地使用了继承亦如此。为遵循Python的总体理念&#xff0c;应让文件尽可能整洁。 Python在这方面提供了帮助&#xff0c;允许将类存储在模块中&#xff0c;然后在主程序中导入所需的模块。 导入单个类 下…...

Deepseek实现本地电影文件批量重命名为infuse格式,可匹配IMDB

import os from openai import OpenAI# 初始化DeepSeek客户端 client OpenAI(api_key"<DeepSeek API Key>", base_url"https://api.deepseek.com")def parse_filename_with_deepseek(filename):"""使用DeepSeek API解析文件名并生成…...

Nginx部署的前端项目刷新404问题

1&#xff0c;查看问题 我部署的81端口是监听tlias项目的&#xff0c;我直接访问端口页面可以出现内容。 我在浏览器舒服端口之后回车&#xff0c;会重定向页面。但是我在重定向之后的页面刷新浏览器就会出现404的问题。 下面是刷新浏览器后的效果 2&#xff0c;在nginx.cnf …...

Boot 系统选择U启动

1.进入Boot 系统 F2 或 Del Boot --->Boot 0ption Priorities #4 KingstwongDataTravele 是U盘 调整搭到#1 2.保持重启就好...

XSLT 编辑 XML:深度解析与实际应用

XSLT 编辑 XML&#xff1a;深度解析与实际应用 引言 XML&#xff08;可扩展标记语言&#xff09;和XSLT&#xff08;可扩展样式表语言转换&#xff09;是处理和转换XML数据的重要工具。本文将深入探讨XSLT在编辑XML文档中的应用&#xff0c;包括其基本概念、语法结构、以及实…...

项目文章 | PNAS 斑马鱼转录因子ChIP-seq助力解析GATA6突变相关的肝脏疾病机制

近日&#xff0c;西南大学阮华/黄红辉团队联合重庆大学邱菊辉/王贵学团队在PNAS发表了题为“An animal model recapitulates human hepatic diseases associated with GATA6 mutations”的研究论文。该研究构建了一个gata6敲除斑马鱼模型&#xff0c;它重现了gata6突变患者的大…...

easyexcel-导入(读取)(read)-示例及核心部件

文章目录 导入(读取)(read)-示例及核心部件导入(读取)(read)-核心部件EasyExcel(EasyExcelFactory) # 入口read() # read()方法用于构建workbook(工作簿)对象&#xff0c;new ExcelReaderBuilder()doReadAll()这里选XlsxSaxAnalyser这个实现类吧然后到这个类XlsxRowHandler&…...

作业day3

请使用dup2 fgets printf 实现文件拷贝功能、 文件1&#xff1a; 复后文件&#xff1a; #define BUFFER_SIZE 1024 void file_copy(const char* src_file, const char* dest_file) { int src_fd, dest_fd; char buffer[BUFFER_SIZE]; // 打开源文件 src_fd open(s…...

第五节 MATLAB命令

本节的内容将提供常用的一些MATLAB命令。 在之前的篇章中我们已经知道了MATLAB数值计算和数据可视化是一个交互式程序&#xff0c;在它的命令窗口中您可以在MATLAB提示符“>>”下键入命令。 MATLAB管理会话的命令 MATLAB提供管理会话的各种命令。如下表所示&#xff1a;…...

Oracle 普通用户连接hang住处理方法

一、现象说明 $ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Wed Dec 18 16:49:19 2024 Version 19.11.0.0.0Copyright (c) 1982, 2020, Oracle. All rights reserved.Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Pro…...

理解C++中的右值引用

右值引用&#xff0c;顾名思义&#xff0c;就是对一个右值进行引用&#xff0c;或者说给右值一个别名。右值引用的规则和左值一用一模一样&#xff0c;都是对一个值或者对象起个别名。 1. 右值引用和左值引用一样&#xff0c;在定义的同时必须立即赋值&#xff0c;如果不立即赋…...

02-机器学习-核心概念

以下是机器学习核心概念的详细梳理。 1. 机器学习三大范式 类型定义典型应用监督学习使用带标签的数据训练模型&#xff0c;预测未知数据的标签。分类&#xff08;邮件垃圾过滤&#xff09;、回归&#xff08;房价预测&#xff09;无监督学习从无标签的数据中发现隐藏模式或结…...

1.26 实现文件拷贝的功能

使用dup2fgetsprintf实现文件拷贝的功能。 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #in…...

ES6+新特性,var、let 和 const 的区别

在 JavaScript 中&#xff0c;var、let 和 const 都用于声明变量&#xff0c;但它们有一些重要的区别&#xff0c;主要体现在 作用域、可变性和提升机制 等方面。 1. 作用域&#xff08;Scope&#xff09; var: var 声明的变量是 函数作用域&#xff0c;也就是说&#xff0c;它…...

HarmonyOS简介:HarmonyOS核心技术理念

核心理念 一次开发、多端部署可分可合、自由流转统一生态、原生智能 一次开发、多端部署 可分可合 自由流转 自由流转可分为跨端迁移和多端协同两种情况 统一生态 支持业界主流跨平台开发框架&#xff0c;通过多层次的开放能力提供统一接入标准&#xff0c;实现三方框架快速…...

嵌入式C语言:结构体对齐

目录 一、对齐的原因 1.1. 硬件访问效率 1.2. 内存管理简化 1.3. 编译器优化 1.4. 代码示例 二、对齐规则 2.1. 基本数据类型对齐 2.2. 结构体成员对齐 2.3. 结构体整体对齐 2.4. 代码示例 三、对齐控制 3.1. 使用 #pragma pack 3.2. 使用 __attribute__((packed)…...

【Rust自学】15.5. Rc<T>:引用计数智能指针与共享所有权

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 15.5.1. 什么是Rc<T> 所有权在大部分情况下都是清晰的。对于一个给定的值&#xff0…...

谈谈RTMP|RTSP播放器视频view垂直|水平反转和旋转设计

技术背景 我们在做RTMP|RTSP播放器的时候&#xff0c;有这样的技术诉求&#xff0c;有的摄像头出来的数据是有角度偏差的&#xff0c;比如“装倒了”&#xff0c;或者&#xff0c;图像存在上下或者左右反转&#xff0c;这时候&#xff0c;就需要播放器能做响应的处理&#xff…...

decison tree 决策树

熵 信息增益 信息增益描述的是在分叉过程中获得的熵减&#xff0c;信息增益即熵减。 熵减可以用来决定什么时候停止分叉&#xff0c;当熵减很小的时候你只是在不必要的增加树的深度&#xff0c;并且冒着过拟合的风险 决策树训练(构建)过程 离散值特征处理&#xff1a;One-Hot…...

GO语言 链表(单向链表

链表的前提 GO语言的链表类似于C语言的链表&#xff0c;它通过结构体和结构体指针实现。 结构体 GO语言定义结构体如下 type user struct {name stringage intnext *user } 结构体指针 结构体指针就是指向结构体的指针&#xff0c;我们在链表中会用到结构体指针实现链…...