C语言实现二叉查找树删除(附完整代码+图解分析)

读书笔记:算法图解 using Python 读书笔记:算法图解 using Python 阅读书目:[美] Aditya Bhargava. “算法图解” 写在前面: 作者称自己是“视觉型学习者,对图解式写作风格钟爱有加”。这一点和我学东西的思维方式很想,对作者很有好感。事实上在阅读过程中也感到很愉快,有些类似近藤麻理惠《怦然心动的人生整理魔法》的图解和讲解方式,深入浅出,常看常新。 阅读这本书主要是想帮自己回忆上课学过的数据结构和算法的相关内容,希望帮自己建立起形象的体系和深刻的理解。此外,当时上课是基于C/C++,这次学习数据结构和算法希望能 阅读详情

第一章:二叉查找树删除操作概述

二叉查找树(Binary Search Tree, BST)的删除操作是其核心操作之一,相较于插入和查找,删除涉及更多边界情况和结构调整。根据待删除节点的子节点数量,删除操作可分为三种情形,每种情形需采用不同的处理策略以维持BST的有序性质。

删除节点的三种情形

  • 无子节点(叶节点):直接移除该节点,不影响树结构。
  • 仅有一个子节点:将该节点的父节点指向其唯一子节点,绕过当前节点。
  • 有两个子节点:需找到其中序后继(右子树中的最小节点)或中序前驱(左子树中的最大节点),用其值替换当前节点值,再递归删除后继或前驱节点。

Go语言实现示例


// TreeNode 定义二叉树节点
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// Delete 删除BST中指定值的节点
func Delete(root *TreeNode, val int) *TreeNode {
    if root == nil {
        return nil
    }
    if val < root.Val {
        root.Left = Delete(root.Left, val)
    } else if val > root.Val {
        root.Right = Delete(root.Right, val)
    } else {
        // 找到目标节点,开始处理三种情况
        if root.Left == nil {
            return root.Right // 无左子树或无子节点
        }
        if root.Right == nil {
            return root.Left // 无右子树
        }
        // 有两个子节点:找右子树中的最小节点(中序后继)
        minNode := findMin(root.Right)
        root.Val = minNode.Val                    // 替换值
        root.Right = Delete(root.Right, minNode.Val) // 删除后继
    }
    return root
}

// findMin 辅助函数:查找最小值节点(最左节点)
func findMin(node *TreeNode) *TreeNode {
    for node.Left != nil {
        node = node.Left
    }
    return node
}

操作复杂度对比

情形时间复杂度空间复杂度
叶节点删除O(h)O(h)
单子节点删除O(h)O(h)
双子节点删除O(h)O(h)
其中 h 为树的高度,在平衡情况下为 O(log n),最坏情况下为 O(n)。

第二章:二叉查找树基础与删除逻辑分析

2.1 二叉查找树的结构定义与特性

基本结构定义
二叉查找树(Binary Search Tree, BST)是一种递归数据结构,其中每个节点包含一个键、一个关联值、一个指向左子树的引用和一个指向右子树的引用。左子树的所有节点键值小于当前节点,右子树的所有节点键值大于当前节点。

type TreeNode struct {
    Key   int
    Val   interface{}
    Left  *TreeNode
    Right *TreeNode
}
上述 Go 语言结构体定义了二叉查找树的节点。Key 用于比较大小以维持树的有序性,Left 和 Right 分别指向左、右子树,形成递归嵌套结构。
核心特性
  • 中序遍历结果为严格递增序列
  • 左子树所有节点键值均小于根节点
  • 右子树所有节点键值均大于根节点
  • 无重复键(通常设计下)

2.2 删除操作的三种情况分类解析

在二叉搜索树中,删除操作需根据节点子节点数量分为三种情况处理。
情况一:待删除节点为叶子节点
该节点无左右子树,可直接移除。例如:
// node 为叶子节点
if node.Left == nil && node.Right == nil {
    node = nil
}
逻辑分析:无需结构调整,仅更新父节点对应指针即可。
情况二:仅有一个子节点
将该节点的父节点指向其唯一子节点。
  • 左子存在:父节点接左子
  • 右子存在:父节点接右子
情况三:有两个子节点
需找到中序后继(右子树最小值)替代当前节点值,再递归删除后继节点,确保BST性质不变。

2.3 查找待删除节点的定位策略

在二叉搜索树中,删除操作的第一步是准确查找到目标节点。该过程依赖于BST的有序特性:左子树所有节点值小于根节点,右子树反之。
递归查找路径追踪
通过比较目标值与当前节点值,决定递归方向,直至命中或为空。
func findNode(root *TreeNode, val int) *TreeNode {
    if root == nil || root.Val == val {
        return root
    }
    if val < root.Val {
        return findNode(root.Left, val)
    }
    return findNode(root.Right, val)
}
上述代码中,findNode 函数依据BST性质逐层缩小搜索范围。若当前节点为空或匹配成功,则返回该节点;否则根据大小关系进入左或右子树继续查找。
查找效率分析
  • 平均时间复杂度为 O(log n),适用于平衡树结构
  • 最坏情况下退化为 O(n),如树呈链状结构

2.4 替代节点的选择原则与继承关系

在分布式系统中,替代节点的选取直接影响系统的容错性与数据一致性。选择替代节点时需遵循三大原则:**拓扑邻近性**、**负载均衡性**和**状态健康度**。
选择原则详解
  • 拓扑邻近性:优先选择同一机架或区域内的节点,降低网络延迟;
  • 负载均衡性:避免将压力集中于单一节点,通过实时指标筛选低负载节点;
  • 状态健康度:依赖心跳机制判断候选节点的可用性。
继承关系建模
当主节点失效,替代节点需继承其数据状态与会话上下文。以下为继承逻辑示例:
func (n *Node) InheritFrom(primary *Node) error {
    n.Data = primary.Data.Copy()     // 继承数据快照
    n.Version = primary.Version      // 版本号同步
    n.SessionTokens = primary.SessionTokens // 会话令牌迁移
    return nil
}
上述代码中,Data.Copy()确保深拷贝避免共享引用,Version同步防止脑裂,SessionTokens迁移保障客户端连接连续性。继承过程需原子化执行,通常结合日志复制(如Raft)实现一致性。

2.5 删除后树结构的平衡性影响分析

在二叉搜索树中删除节点后,树的平衡性可能被破坏,进而影响后续操作的时间复杂度。为维持高效性能,需引入自平衡机制。
平衡性破坏场景
删除内部节点尤其是高度较高的子树根节点时,可能导致左右子树高度差超过1,打破AVL树或红黑树的平衡约束。
典型修复策略
  • 旋转操作:包括左旋、右旋、左右双旋和右左双旋
  • 颜色重涂:应用于红黑树,调整节点颜色分布
  • 高度更新:自底向上回溯,修正各节点高度值
TreeNode* rebalance(TreeNode* node) {
    updateHeight(node);
    int balance = getBalance(node);
    if (balance > 1 && getBalance(node->left) >= 0)
        return rightRotate(node); // LL型
    if (balance < -1 && getBalance(node->right) <= 0)
        return leftRotate(node);  // RR型
    // 其他情况处理...
}
该函数在删除后调用,通过判断平衡因子决定是否旋转,确保整棵树恢复平衡状态。

第三章:核心删除算法的C语言实现

3.1 节点结构体与函数接口设计

在分布式系统中,节点是构成集群的基本单元。为实现高效通信与状态管理,需精心设计节点的结构体及其对外暴露的函数接口。
节点结构体定义
type Node struct {
    ID       string            // 唯一标识符
    Address  string            // 网络地址
    Role     string            // 角色(leader/follower)
    State    map[string]string // 存储状态数据
    Heartbeat time.Time        // 最近心跳时间
}
该结构体封装了节点的核心属性:ID用于唯一识别,Address支持网络寻址,Role决定行为逻辑,State保存本地数据副本,Heartbeat用于故障检测。
核心接口设计
采用面向接口编程,定义如下方法:
  • Start():启动节点并监听请求
  • SendVote(req VoteRequest) VoteResponse:处理投票请求
  • AppendEntries(entries []LogEntry) bool:接收日志复制
这些方法构成了共识算法通信的基础,确保节点间行为一致且可扩展。

3.2 单子树节点的删除与指针重连

在二叉搜索树中,删除仅有一个子节点的节点时,需将其父节点直接指向该节点的唯一子节点,实现指针重连。
操作步骤
  • 定位待删除节点及其父节点
  • 判断子节点位于左或右分支
  • 将父节点对应指针重定向至唯一子节点
代码实现
func deleteNode(root *TreeNode, key int) *TreeNode {
    if root == nil { return nil }
    if key < root.Val {
        root.Left = deleteNode(root.Left, key)
    } else if key > root.Val {
        root.Right = deleteNode(root.Right, key)
    } else {
        if root.Left == nil { return root.Right }
        if root.Right == nil { return root.Left }
        // 此处为单子树处理:仅保留非空子树
        if root.Left == nil || root.Right == nil {
            if root.Left != nil {
                return root.Left
            }
            return root.Right
        }
    }
    return root
}
上述逻辑确保了结构完整性,时间复杂度为 O(h),其中 h 为树高。

3.3 叶子节点与双子树节点的处理方案

在分布式树形结构中,叶子节点与双子树节点的处理策略直接影响系统的负载均衡与容错能力。
叶子节点的优化策略
叶子节点不参与数据转发,仅负责本地计算与存储。为降低资源浪费,可采用惰性激活机制:
// 惰性激活:仅在收到任务时初始化资源
func (n *Node) Activate() {
    if n.IsLeaf && !n.IsActive {
        n.AllocateMemory()
        n.StartHeartbeat()
    }
}
该方法延迟资源分配,避免空转开销。
双子树节点的同步机制
具备两个子节点的非叶节点需确保数据一致性。使用版本号比对实现轻量同步:
字段类型说明
versionuint64子树数据版本号
checksumstring数据校验值
当版本不一致时触发增量同步,减少网络传输压力。

第四章:代码实现与调试验证

4.1 完整C语言代码实现与关键注释

在嵌入式系统开发中,C语言因其高效性和底层控制能力被广泛采用。以下是一个完整的C程序示例,实现了基本的温度传感器数据读取与处理。
核心功能实现

#include <stdio.h>

// 模拟ADC读数(0-1023对应0-5V)
int read_adc() {
    return 768; // 假设读数为768
}

// 将ADC值转换为摄氏度
float convert_to_celsius(int adc_value) {
    float voltage = (adc_value * 5.0) / 1023.0;
    float temperature = (voltage - 0.5) * 100; // LM35传感器公式
    return temperature;
}
上述代码中,read_adc() 模拟从ADC寄存器获取原始值,convert_to_celsius() 根据LM35传感器线性特性进行电压到温度的转换。
主程序流程
  • 调用 read_adc() 获取原始数据
  • 传入转换函数得到实际温度值
  • 通过标准输出打印结果

4.2 构建测试用例进行功能验证

在开发过程中,构建全面的测试用例是确保系统功能正确性的关键步骤。测试应覆盖正常流程、边界条件和异常场景,以提升代码的健壮性。
测试用例设计原则
  • 覆盖核心业务逻辑路径
  • 包含输入边界值与非法值
  • 模拟真实用户操作序列
示例:Go 单元测试代码
func TestCalculateDiscount(t *testing.T) {
    tests := map[string]struct {
        price    float64
        isMember bool
        expected float64
    }{
        "regular user no discount": {100, false, 100},
        "member with 10% discount": {100, true, 90},
    }

    for name, tc := range tests {
        t.Run(name, func(t *testing.T) {
            result := CalculateDiscount(tc.price, tc.isMember)
            if result != tc.expected {
                t.Errorf("expected %f, got %f", tc.expected, result)
            }
        })
    }
}
该测试使用表驱动方式组织多个用例,tests 结构体定义了输入与预期输出,通过 t.Run 分别执行并定位失败项,增强了可读性和可维护性。

4.3 使用图解对比删除前后树结构变化

在二叉搜索树中删除节点时,结构可能发生显著变化。通过图示可清晰观察操作前后差异。
删除前树结构:
    5
  /   \
  3     8
 / \     /\
2  4   7  9
删除节点3后:
    5
  /   \
  4     8
 /       /\
2      7  9
  • 节点3为双子节点,替换为其右子树最小值(4)
  • 原位置由4填补,子树重新链接
  • 整体BST性质保持不变
// 删除节点核心逻辑片段
if node.Left != nil && node.Right != nil {
    min := findMin(node.Right)
    node.Val = min.Val
    node.Right = deleteNode(node.Right, min.Val)
}
该代码段处理双子节点情况:用右子树最小值覆盖当前节点,再递归删除该最小值节点,确保结构合规。

4.4 常见错误分析与调试技巧

典型运行时错误识别
在开发过程中,空指针引用和类型转换异常是最常见的问题。例如,在Go语言中对nil切片进行操作会引发panic:
var data []string
for _, v := range data[0] {  // 可能触发panic: runtime error
    fmt.Println(v)
}
该代码未判断切片是否为nil或空,正确做法是先校验长度:if len(data) > 0。
高效调试策略
使用日志分级记录有助于快速定位问题根源。推荐采用结构化日志输出:
  • DEBUG:用于变量状态追踪
  • INFO:关键流程节点标记
  • ERROR:异常捕获及堆栈打印
结合断点调试工具,可精准分析函数调用链中的数据流偏差,提升修复效率。

第五章:总结与拓展思考

性能优化的实际路径
在高并发系统中,数据库查询往往是瓶颈所在。通过引入缓存层(如 Redis)并结合本地缓存(如 Go 中的 sync.Map),可显著降低响应延迟。

// 使用本地缓存避免频繁访问数据库
var localCache = sync.Map{}

func getCachedUser(id int) (*User, error) {
    if val, ok := localCache.Load(id); ok {
        return val.(*User), nil
    }
    user, err := queryUserFromDB(id)
    if err != nil {
        return nil, err
    }
    localCache.Store(id, user)
    return user, nil
}
架构演进中的权衡
微服务拆分并非银弹,需根据业务边界合理划分。以下为某电商平台从单体到微服务的迁移效果对比:
指标单体架构微服务架构
部署时间15分钟2分钟(按服务)
故障影响范围全局风险局部隔离
团队协作成本低高(需契约管理)
可观测性的实践建议
完整的监控体系应包含日志、指标和链路追踪。推荐使用 Prometheus 收集指标,搭配 OpenTelemetry 实现跨服务追踪。关键操作应记录结构化日志:
  • 用户登录事件应包含 IP、设备类型、时间戳
  • 支付失败需标记错误码与上下文 trace_id
  • 定期对日志进行采样分析,识别异常模式
一图流掌握二叉排序树:考研408核心考点与C/Python代码实现 二叉排序树(BST)作为一种基础且高效的动态数据结构,其核心原理在于利用“左子树节点值均小于根节点,右子树节点值均大于根节点”的递归定义来组织数据。这一结构巧妙地结合了链式存储的灵活性与二分查找的高效性,旨在同时优化数据的查找、插入与删除操作。在理想情况下,这些操作的时间复杂度可达到O(log n),为解决有序数据的动态管理问题提供了优雅方案。其技术价值不仅体现在算法效率的提升上,更是理解AVL树、红黑树等高级平衡数据结构以及C++ STL中map/set、Java中TreeMap/TreeSet等标准库容 阅读详情

相关推荐

《手撕红黑树:一个通用的 C 语言实现》

本文将带着你手撕一个完整的、泛型的红黑树 C 语言实现。代码支持任意类型的 key 和 value,并提供了初始化、销毁、增删改查等标准接口。我们不仅会贴出核心代码,还会详细分析旋转、插入修复、删除修复等复杂逻辑。

qq_56836848的博客 302

20张图带你彻底搞懂二叉树的删除操作

最近在学习数据结构与算法,记录下二叉树的删除操作是如何实现的,相对于其他的插入,排序等操作。删除操作逻辑上稍微比较复杂,今天通过图形化的方式帮你们彻底搞懂到底是怎么实现删除操作的。话不多说,直接开始。注:本文采用js语言作为演示。

kzj0916的博客 5110

【电商风控】电商风控标注是什么

本篇文章给大家谈谈。

866

二叉树的删除

有序二叉树的删除 三种删除模式: 1、删除叶子节点 (1)找到要删除的叶子节点trageNode (2)找到目标结点的父节点parentNode(考虑是否有父节点) (3)找到删除的节点是父节点的左子树还是右子树 (4)根据前面的情况进行删除 左子树:parent.left = null 右子树:parent.right = nul 2、删除只有一个子树的节点 (1)找到要删除的叶子节点trageNode (2)找到目标结点的父节点parentNode(考虑是否有父节点) (3)找到

cang_ling的博客 4554

在 Windows 上使用 Anaconda 创建 配置 YOLOv8虚拟环境,并更改 pip 源以及以 可编辑模式 安装ultralytics

前往 NVIDIA cuDNN 下载页面,下载与您安装的 CUDA 版本匹配的 cuDNN 版本。:根据您的系统和 CUDA 版本,选择适当的 whl 文件。如下12.7,表示最高可装12.7版本CUDA,与上图中的支持的最高cuda版本一致。,无需重新安装,从而大幅提升开发效率,适用于项目开发、调试或依赖本地未发布的版本时使用,但需确保当前目录包含。:访问 NVIDIA 官方网站,下载与您的显卡和操作系统兼容的 CUDA 版本。首先,确保NVIDIA 显卡支持 CUDA,并安装相应版本的驱动程序。

weixin_44115575的博客 1893

MOSFET和IGBT栅极驱动器电路的基本原理学习(2)

1.PWM直接驱动 驱动主开关晶体管栅极的最简单方法是利用 PWM 控制器的栅极驱动输出,如图 (1)如 图 8中所示,PWM 控制器和 MOSFET 之间可能有较大距离。由于栅极驱动和接地环路迹线形成的环路,这个距离形成了寄生电感,从而降低了开关速度,并导致栅极驱动波形中形成振铃。为了降低与栅极驱动连接相关的电感,需要更宽的 PCB 迹线。 (2)直接栅极驱动的另一个问题是PWM 控制器的驱动电流能力有限。极少有集成电路能提供高于 1A 的峰值栅极驱动能力。 2.旁路电容的确定 (1)位置 如果是独立的

weixin_43732932的博客 5831

二叉树的前中后序查找

public class BinaryTreeDemo { public static void main(String[] args) { //创建一颗二叉树 BinaryTree binaryTree = new BinaryTree(); //创建需要的结点 HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new HeroNode(2, "吴用"...

weixin_49849351的博客 574

MindIE与vLLM-Ascend性能对决:Qwen3在昇腾910B上的推理效率实测

本文深度对比了昇腾910B平台上两大推理框架MindIE与vLLM-Ascend的性能表现。通过实测Qwen3系列模型,详细分析了二者在单卡、多卡场景下的推理效率、扩展性及生产环境适用性,为AI算力基础设施选型提供关键参考。

weixin_29214335的博客 1185

数据结构——二叉排序树的删除操作(非递归)

二叉排序树的删除操作

xinzhi1992的博客 5464

Android——Handler详解

1. 简介 Handler是一套 Android 消息传递机制 可以说只要有异步线程与主线程通信的地方就一定会有 Handler。 在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理 使用Handler消息传递机制主要是为了多个线程并发更新UI的同时,保证线程安全 2. 相关概念解释 Handler、Message、Message Queue、Looper Android消息机制: 以Handler的sendMes

Yawn 7万+

Windows系统中 Xmanager 6 企业版下载安装激活教程

Xmanager 6 企业版安装激活教程 1.Xmanager 6 下载网址:https://yunpan.360.cn/surl_yrJrWq3GmjN 2. 双击 Xmanager-6.0.0169r 安装 3. 点击运行按钮 4. 点击下一步 5. 选择我接受许可证协议中的条款(A), 点击下一步。 6. 输入用户名:byg,公司名称:microsoft,序...

mry6的博客 9873

二叉树增删改查C语言实现

【数据结构】对二叉树的创建及增删改查C语言

qq_64021539的博客 472

YOLOv8的特征蒸馏代码应用讲解(CWD/MGD/mimic/在线蒸馏/逻辑蒸馏)

基于YOLOv8的逻辑蒸馏、特征蒸馏、在线蒸馏等方法代码介绍。

qq_41920323的博客 2583

C语言 AVL平衡二叉查找树 插入/删除/遍历/查找

AVl树:平衡二叉查找树,树中任何节点的两个子树的高度最大差别为1。如下图所示 AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。 如果在AVL树中插入或删除节点后,使得高度之差大于1。此时,AVL树的平衡状态就被破坏,它就不再是一棵二叉树;为了让它重新维持在一个平衡状态,就需要对其进行旋转处理。 1. AVL树的结构     typedef struct AVLTreeN...

HardessGod的博客 1734

UDPProbe UDP端口存活探测(发送特征包+响应分析)、UDP服务识别

qDebug() << "收到响应:" << ip.toString() << ":" << port << " 服务:" << serviceName << " 响应长度:" << response.size();qDebug() << "开始探测:" << targetIp << ":" << port << " 超时时间:" << timeout << "ms";qInfo() << "\n==================== UDP探测结果 ====================";

寒寒豆豆软件公司的博客 147

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C语言实现二叉查找树平衡旋转:5步掌握左旋、右旋、双旋核心技术

掌握C语言二叉查找树的平衡旋转,5步学会左旋、右旋与双旋核心技巧。适用于AVL树调整,提升查找效率,代码清晰易实现,解决树失衡问题,值得收藏。

LogicShoal的博客 794

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

二叉搜索树的实现(C语言)

二叉搜索树的实现(C语言)

2301_76269963的博客 3888

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C语言平衡二叉搜索树,图解数据结构:自平衡二叉查找树(C语言实现)

(1)二叉查找树的定义在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。每一棵子树的根叫做根r的儿子,而r是每一棵子树的根的父亲。具有N个节点的每一棵二叉树都将需要...

weixin_42510768的博客 336

图解二叉树节点的查找,插入和删除操作,求高度等等运算集合

首先这三种操作都是基于二叉查找树所进行的操作,因此开始之前应该建立二叉查找树。 查找和插入由于比较好理解,直接看代码吧. 查找和插入://这个部分参考胡昭民编著清华出版的数据结构,有所改动。 #include <stdio.h> #include <stdlib.h> struct tree { int data; struct tree *left,*right;...

计算机科学与技术专业学生的成长之路 1044

图解数据结构:自平衡二叉查找树(C语言实现)

(1)二叉查找树的定义 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。每一棵子树的根叫做根r的儿子,而r是每一棵子树的根的父亲。 具有N

APlus 740

二叉树系列:初探二叉树,c语言实现

端午节假期的最后一天,天气凉爽,我下午该回学校了。原本,我昨天就该写下二叉树的博文,但是由于在二叉树删除这块的功能实现不尽人意,所以我推迟了,希望将其改进后再进行记录。早上趁着清醒,我如愿地改进了二叉树的删除功能,特此记录想法的美好瞬间。  1、二叉树的基本概念         二叉树的特点是每个结点至多有二棵子树,并且子树之间有左右之分。 二叉树的其他特性可以参考博文链接,这里按照我自己的

LWJ的专栏 570

AVL树(一)之 图文解析 和 C语言的实现

转载-原文地址:https://www.cnblogs.com/skywang12345/p/3576969.html 概要 本章介绍AVL树。和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现。本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++和Java版本的实现。 建议:若您对"二叉查找树"不熟悉,建议先学完"二叉查找树"

HHHHHHep的博客 579

深入浅出平衡二叉树:AVL 树插入与删除的核心逻辑与 C 语言实战

普通的二叉搜索树在极端情况下会退化成链表?本文带你从零使用 C 语言硬核实现 AVL 树。文章通过图文结合的方式,详细拆解了左旋右旋的核心原理,并分步骤剖析了全网最难啃的 AVL 树插入与双孩子节点删除代码,助你彻底跨越数据结构大山!

2301_80100578的博客 361

AVL树图文解析以及实现

本文原理转载自:AVL树图文解析和C实现 代码实现是自己写的~   概要 本章介绍AVL树。和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现。本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++和Java版本的实现。建议:若您对"二叉查找树"不熟悉,建议先学完"二叉查找树"再来学习AVL树。 目录 1. AVL树的介绍 2. AVL树...

silverBlack 408

大刀阔斧,抽丝剥茧:评红黑树系列文章

大刀阔斧,抽丝剥茧:评红黑树系列文章作者:July  二零一一年一月三十日本文参考:本BLOG内红黑树系列的四篇文章:I、   教你透彻了解红黑树:http://blog.youkuaiyun.com/v_JULY_v/archive/2010/12/29/6105630.aspxII、 红黑树算法的层层剖析与逐步实现  [此文被推荐]http://blog.youkuaiyun.com/v_JULY_v/archive/2010/12/31/6109153.aspxIII、教你彻底实现红黑树:红黑树的c源码实现与剖析http:/

结构之法 算法之道 1万+

红黑树图文详解:C语言200行实现插入删除与验证

平衡二叉树是计算机科学中用于保持数据有序性的重要数据结构,而红黑树作为其中最典型的松弛平衡实现,以五条性质约束保障了最坏情况下的对数查找效率。它的核心机制在于节点染色与旋转操作,通过“变色+左旋/右旋”的组合策略,在插入与删除时维持树的平衡,相比AVL树减少了旋转次数,综合性能优秀。从C语言的工程实践视角来看,手写红黑树能够深入理解指针操作与递归迭代的精髓。红黑树广泛应用于STL map、Java TreeMap、Linux内核等场景,是面试与工程中的高频考点。本文通过图文详解和一套约200行的C语言完整实

weixin_34109408的博客 238
上一篇: 单生产者多消费者场景下的循环缓冲区设计,你真的懂吗?
下一篇: 结构体指针如何安全传递给函数?这6个原则每个程序员都该牢记
VarPerch
博客等级 码龄1年 146粉丝 1961原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值