当前课程知识点:数据结构(上) > 第五章 二叉树 > (d)二叉树实现 > 05D-4 高度更新
以下我们就以高度更新接口为例
介绍背后的算法
以及这个接口的实现方法
因为我们这里还没有接触到
二叉树的更多变种
所以我们所谓的高度依然采用此前
常规的定义
具体来说 对于任何一个节点x
所谓它的高度其实就是
在以它为根的子树中
从它通往那个最深的
叶节点的路径长度
只不过这里我们需要
考察几种特殊的情况
比如第一种就是只有单个节点的情况
你应该记得我们将这种
只有单个节点的树的高度取作0
而另一些时候呢
我们可能要考虑一些
根本就不存在任何节点的树
也就是我们所说的空树
同样地 你也应该记得我们此前约定
空树的高度为-1
那么这种一般性的情况
退化的情况
以及极其退化的情况
又应该如何统一呢?
这里我们采用了一种
通过宏定义的封装的方式
通过重新命名一个新的
等价意义上的高度
我们的确可以将常规情况下的高度
与退化情况下的高度统一起来
使得我们此后对算法的描述和理解
可以更为简便
同时也不致于影响到算法的正确性
我们知道 一个节点的高度
之所以会发生变化
是由于它的左孩子
或者右孩子的高度
发生了变化而引起的
准确地讲 一个节点的高度
应该恰好等于它的左孩子
与右孩子高度中的更大者 再加1
因此我们也就可以相应地得到
这么样一个对任意节点x
进行高度更新的算法
一旦x的左孩子与右孩子的高度确定
我们就可以在它们之间取出更大者
并且在此基础上再累加1
就可以得到x节点的高度
这种高度的更新往往会体现出一种
层层递进的连锁形式
比如说 如果x的父节点存在
那么父节点很有可能
也会因为x的高度
发生变化而高度变化
而再往上 如果有祖父节点
乃至有曾祖父节点
那么这些祖先节点的高度
都有可能发生变化
因此如果要对全树做整体的高度更新
我们往往需要从某一个节点
比如x出发
向上逐层地追溯它的历代祖先
直到最终抵达根节点
这样一个过程也自然地可以用我们的
新的一个算法来实现
也就是updateHeightAbove 参数是x
也就是说 经过逐层逐层逐层
逐层的上升
抵达根之后
如果我们依然希望向上追溯
就会抵达根的父亲 也就是空
此时算法终止是再自然不过的了
由此我们也可以看到
整个这样的过程需要从x开始
遍历它的所有历代祖先
这个路径反过来也恰好是
从根节点出发
向下而行
抵达这个节点的那条唯一的通路
我们讲过这个恰好就是
x这个节点的深度
因此这个算法的复杂度
正比于x节点的深度
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验