二叉树链表中一个结论的证明以及 Successor() 函数中算法的解释

首先, 先明确 “结点 x 的 successor” 的概念。 这句话的概念是, successor 是整个二叉树中, key 仅比 x 的 key 大的结点。

求证: 若 x 有两个孩子, 那么其 successor 没有左孩子。

证明: 若 x 有两个孩子, 则其右子树存在。在二叉树链表中, 对于任意 x 的右子树都是 key 比 x 的 key 大的结点的集合, 即{y|y->key > x->key}。根据 successor  的定义, 若 x->rightChild ≠ nil, 则 successor = Min({y|y->key > x->key})。意味着如果节点 y 是 x 的 successor 且 x 有右孩子, 那么 y 必为 x 的右子树的最左端结点, 所以 y 必然没有左孩子。

对于 Successor() 函数中算法的解释:

1. 若 x 有右孩子, 参见前一证明中的结论。
2. 若 x 没有右孩子, 那么 x 必为以 x 为头结点的子树的 key 最大的结点, 那么若要寻找 successor, 就必须扩大子树的范围, 将 x 的父结点作为新子树的头结点, 记为 p(x)。而 p(x) 存在三种情况:

2.1 若 p(x) = nil, 则搜索结束, 因为这意味着 x 的 key 是整个二叉树中最大的 key, 所以 successor = nil。
2.2 若 p(x) ≠ nil, 且 x 为 p(x) 的左节点,则 successor = p(x)。因为若存在结点 y = successor 且 y ≠ p(x), 则 x->key < y->key < p(x)->key, 根据二叉树链表的规则, y 应满足 y ∈ {y|y->key > x->key} 即 x 的右子树, 但 x 是没有右孩子的。

2.3 若 p(x) ≠ nil, 且 x 为 p(x) 的右节点,则显然 p(x)->key < x->key 即 x 仍为新子树中 key 最大的结点, 所以仍需继续扩大子树的规模, 将当前头结点的父节点作为新子树的头结点进行判断,将其记为 p(y) 则 p(y) 又分为三种情况:

2.3.1 若 p(y) = nil, 则等同于 2.1。
2.3.2 若 p(y) ≠ nil, 且 p(x) 为 p(y) 的右节点,则显然 p(y)->key < p(x)->key < x->key 显然 p(y) 不是 successor, 所以重复 2.3 中的行为继续搜索。
2.3.3 若 p(y) ≠ nil, 且 p(x) 为 p(y) 的左节点,则 p(y) = successor。 因为此时 x = Max({z|z->key <= p(y)->key}) ⇔ p(y) = Min({k|k->key > x->key})联立之前证明中的结论 successor = Min({k|k->key > x->key}) 可得 p(y) = successor。

时间: 2024-11-08 22:25:04

二叉树链表中一个结论的证明以及 Successor() 函数中算法的解释的相关文章

POJ 3352 Road Construction 中一个结论的证明

题面 分析: 很多人都给出了做法,在这里不赘述.大概就是先把桥找出来,然后边双缩点,最后统计新图上的度数.因为缩点后为一棵树,所以度数为1(即为叶子)的点的数目+1再除以2下取整就是答案. 这里主要证明一下为什么是对的. 表达式:\[答案=\lfloor\frac{叶子数+1}{2}\rfloor\] 证明:考虑一棵树中,我们找出带权重心,使得重心下每个子节点的叶子节点数尽量的平均(具体实现不讲了),那么在这棵尽量平均的树上,我们每次取两个根节点下子树不同的叶子节点连边,比如说最左边连最右边,左

MVC中一个Form多个submit在controller中如何区分提交的是那个submit(如:登陆和注册)

1. 用Html.BeginForm(ActionName,ControllerName,Post)来实现controller-action的路由, 2. Form里的每个input的name值统一,比如都命名为commandName, 每个input的value设为不同值. 3. 更改Action处理方法的参数, 添加一个参数为commandName,则commandName的值为input设置的value. 在controller中

C# 在Visual Studio中一个项目有两个Main函数, 怎么设置哪个是入口?取代csc /main选项。

namespace ConsoleApp1{class Program{static void Main(string[] args){Console.WriteLine("Program");Console.ReadKey();}} class Program1{static void Main(string[] args){Console.WriteLine("Program1");Console.ReadKey();}}}然后在菜单Project->**

Sql Server 中一个非常强大的日期格式化函数

Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06 Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16 Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06 Select CONVERT(varchar(100),

函数中的$input

$input 在此属于一个特殊变量,一般在函数中用于接收输入 1 function FindWindowsFolder 2 { 3 $input | where-object {$_.Name -eq "Windows"} 4 } 5 6 ls -path c:\ | FindWindowsFolder 结果为:

python之匿名函数以及在内置函数中的使用

一. 匿名函数 Python使用 lambda 来创建匿名函数.所谓匿名函数,它与用 def 关键字定义的函数相比,没有函数名称. 1.1 匿名函数定义及特点 语法: lambda [para1, para2, ...]: expression 从匿名函数的定义格式可以看出: 1. lambda后没有跟函数名,这就是匿名函数名称的由来. 2. [para1, para2, ...]是一个参数列表,它是可选的,而且是任何类型的. 3. expression表达式实现匿名函数功能的过程,并返回操作结

c之二叉树链表操作---建立、(递归)前序遍历、中序遍历、后序遍历

[二叉树链表] 1.节点定义: typedef struct node{ int data; struct node*lchild,*rchild; }Tree,*BiTree; 2.创建二叉树: BiTree creat_Tree(BiTree root,int num){//建立二叉树 if(root==NULL) { root=(Tree *)malloc(sizeof(Tree)); if(root==NULL) { printf("no memory available\n"

(eden)排序二叉树VS二叉树链表

排序二叉树 Description: If you have any doubt on this assignment, please send an email to its author 黎洋. --> 题目大意:请完成下面四个函数的定义(在tree.h文件中),使整个程序能够利用排序二叉树的结构对输入的数(不会出现相同的数),进行排序输出.节点的结构体在下面已给出,这个二叉树的特征是,左子数的值肯定比父节点小,右子树的值肯定比父节点的大.要求大家按照这个结构特征去构建二叉树,最后中序遍历输

list链表之:从链表删除一个节点list_del

从链表删除一个节点使用接口list_del,使用list_del时要非常注意. list_del的实现如下: static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } static inline void __list_del(struct