从 F# 中的二叉搜索树中删除元素

2023-12-03

我正在尝试编写一种方法来从 BST 中删除元素。到目前为止,这就是我所拥有的。我不确定我是否走在正确的轨道上,或者是否有更好的方法通过使用模式匹配来匹配不同的删除情况,即:没有子项、1 个子项、2 个子项。

type 'a bst = NL | BinTree of 'a * 'a bst * 'a bst;;

let rec smallest = function
    | NL -> failwith "tree is empty"
    | BinTree(m, lst, rst) -> if lst = NL then BinTree(m, lst, rst)
                              else smallest lst;;

let rec smallest2 = function
    | NL -> failwith "tree is empty"
    | BinTree(m, lst, rst) -> if lst = NL then m
                              else smallest2 lst;;

let rec rem2 = function
    | NL -> NL
    | BinTree(m, NL, NL) -> NL
    | BinTree(m, NL, rst) -> rst
    | BinTree(m, lst, NL) -> lst
    | BinTree(m, lst, rst) -> BinTree(smallest2 rst, lst, rst);;


let rec rem x = function
    |NL -> failwith "Node doesn't exit"
    |BinTree(m, lst, rst) -> if m = x then rem2 (BinTree(m, lst, rst)) 
                             elif m < x then BinTree(m, lst, rem x rst) 
                             else BinTree(m, rem x lst, rst);;

没有子节点和单个子节点的情况工作得很好,但是当要删除的节点有 2 个子节点时,我不知道如何实现这种情况。我想用其右子树上的最小项目替换该节点的值,然后删除其右子树上的最小项目。


我不太确定我理解你的逻辑remove函数正在尝试实现。通常的方法是编写一个递归函数:

  • if x小于当前,删除x从左子树递归
  • if x大于当前,删除x从右子树递归
  • if x等于当前,删除当前节点并合并两棵树

在 F# 中对此进行编码的方法是使用模式匹配编写递归函数 - 与您编写的函数非常相似:

let rec remove x = function
  | NL -> NL
  | BinTree(m, lst, rst) when x = m -> merge lst rst
  | BinTree(m, lst, rst) when x < m -> BinTree(m, remove x lst, rst)
  | BinTree(m, lst, rst) (* x > m *) -> BinTree(m, lst, remove x rst)

[EDIT以下内容实际上不起作用!]这几乎完成了,但是您需要添加merge功能。 merge函数的逻辑如下:

  • 如果两棵树都是空的,则返回空树
  • 如果剩下的是Bin(n, llst, lrst)右边是rst然后返回一棵包含n with llst在左边并(递归地)合并lrst and rst在右边(因为它们中的元素都大于n).
  • 类似地,如果正确的是Bin左边是其他东西。

这不会产生balanced二叉树,但它是一个好的开始。

EDIT:我认为也许最简单的选择是编写两个函数 - 一个用于删除树中最大的元素,一个用于删除树中最小的元素(然后在合并时,您可以只调用这两个函数之一)。这可能比编写完全通用的删除函数更容易。

以下代码删除最大元素并将其与新树(没有最大元素)一起返回:

let rec remLargest = function
  | NL -> failwith "Tree was empty!"
  | BinTree(m, l, NL) -> m, l
  | BinTree(m, l, r) -> 
      let res, newR = remLargest r
      res, BinTree(m, l, newR)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 F# 中的二叉搜索树中删除元素 的相关文章

  • .Net 中可用的并行技术

    我是 Net 平台的新手 我查了一下 发现 Net中有几种做并行计算的方法 任务并行库中的并行任务 即 Net 3 5 PLINQ Net 4 0 异步编程 Net 2 0 异步主要用于执行 I O 繁重的任务 F 有简洁的语法支持这一点
  • 如何在 F# 中执行 Seq.takeWhile + 一项

    我想编写一个使用谓词过滤序列的函数 但结果还应该包括谓词返回 false 的第一个项目 如果 F 中有一个break关键字 逻辑将是这样的 let myFilter predicate s seq for item in s do yiel
  • 如何向 F# 项目添加第三方 dll 引用?

    我正在向我的 F 项目添加第三方 dll 引用 我在引用中添加了 dll 当我使用它时 即突出显示代码并执行 Alt Ent 我收到错误 命名空间或模块 AZROLESLib 未定义 我是不是错过了什么 简而言之 你必须使用 r path
  • F# - 构造嵌套类型

    我想这是非常基本的 F 问题 类型有 type Id1 Id1 of int type Id2 Id2 of string type Id Id1 Id2 type Child Id Id Smth string list type Nod
  • Parsec 函数“parse”和类“Stream”的类型签名

    约束条件是什么 Stream s Identity t 下面的类型声明是什么意思 parse Stream s Identity t gt Parsec s a gt SourceName gt s gt Either ParseError
  • 将一个列表(n 元组或列表)与另一个列表(也可以是数组)缩放的惯用 F# 方法是什么?

    Given let weights 0 5 0 4 0 3 let X 2 3 4 7 3 2 5 3 6 我想要的是 wX 0 5 2 3 4 0 4 7 3 2 0 3 5 3 6 我想知道一种使用列表和数组来执行此操作的优雅方法 欢迎
  • 在 Symfony3 中覆盖 Doctrine2 类型

    我想用Carbon http carbon nesbot com docs 我的 Symfony 3 2 应用程序中的对象而不是 SPL DateTime 对象 我发现了一组 DoctrineExtension 类here https gi
  • F# 查询,按单列对多个值进行分组

    我有一个 F sql 查询 需要对每组中的两列求和 let financials query for data in dbData do groupValBy data earning data losses data store into
  • 生成 .tail IL 指令的简单 F# 代码是什么?

    我想看看 tailIL 指令 但我一直在编写的使用尾部调用的简单递归函数显然已优化为循环 我实际上是在猜测这一点 因为我不完全确定反射器中的循环是什么样的 我绝对没有看到任何 tail不过操作码 我在项目的属性中检查了 生成尾部调用 我还尝
  • 检查 Perl 函数参数值得吗?

    有很多关于MooseX 方法 签名 http search cpan org perldoc MooseX Method Signatures甚至在此之前 诸如参数 验证 http search cpan org perldoc Param
  • F# 开发和单元测试? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我刚刚开始使用 F 这是我的第一种函数式语言 我一直在准专门使用 C 工作 并且非常喜欢 F 引导我重新思考如何编写代码 我觉得有点迷失方向的一
  • 二叉树和快速排序?

    我有一个家庭作业 内容如下 别生气 担心 我是not请你帮我做作业 编写一个程序 通过使用二分查找的快速排序方法对一组数字进行排序 树 推荐的实现是使用递归算法 这是什么意思 到目前为止 这是我的解释 正如我在下面解释的那样 我认为两者都有
  • 链表分区函数及反转结果

    我编写了这个 F 函数来将列表分区到某个点并且不再进一步 很像之间的交叉takeWhile and partition let partitionWhile c l let rec aux accl accr match accr with
  • 您可以在 clojure defrecord 中指定方法的返回类型吗?

    我已经创建了一个应用程序信息接口和一个类 但是当我查看生成的类时 所有方法的返回类型都是 Object 我可以将返回类型更改为 String 吗 文档说类型提示可以使用 defrecord 但没有给出示例 我能找到的唯一示例是类型提示字段和
  • Haskell 中存在量化值的列表

    我想知道为什么这段代码不进行类型检查 LANGUAGE ScopedTypeVariables Rank2Types RankNTypes OPTIONS fglasgow exts module Main where foo forall
  • 如何检查字符串是否为类型[重复]

    这个问题在这里已经有答案了 我有类型 export type PermissionType creator editor viewer 在运行时 如何检查变量 userInput 是否实际上是上述类型之一 let userInput foo
  • ExcelDna F# 和可选参数

    对于标量 即非类似数组 可选参数 我将使用以下模式
  • 当给定部分限定类型名称时,Type.GetType 如何工作?

    在很多地方我都遇到过以下形式的部分限定类型名称FullTypeName AssemblyName 即像Type AssemblyQualifiedName仅没有版本 区域性和 publicKeyToken 限定符 我的问题是如何将其转换为相
  • 静态成员函数中的封闭类的 C++ 类型

    我认为这是完全不可能的 但如果呢 在任何版本的 C 中 是否有可能以某种方式获取静态成员函数中封闭类的类型 class Impossible public static void Fun typedef Impossible Enclosi
  • 结合记忆和尾递归

    是否有可能以某种方式将记忆和尾递归结合起来 我目前正在学习 F 理解这两个概念 但似乎无法将它们结合起来 假设我有以下内容memoize函数 来自现实世界的函数式编程 http www manning com petricek let me

随机推荐

  • CSS 边框向内弯曲

    I want to build the container with bended borders inside the element Is it possible to do using only css If it is contai
  • Angular 2 表单“找不到控件”

    我正在尝试使用 Angular 2 Forms 进行验证 但是当我尝试添加多个控件时 似乎它只是被忽略了 我遵循了许多不同的指南 看看其他人是如何做的 但这些方法似乎都不起作用 我一直在我的模板中做的是
  • 使用 QT 设计器创建的 PyQt5 程序从终端打开时不显示任何窗口

    我使用 QT Designer 没有任何问题 但今天我开始了一个新的 ubuntu 18 04 安装 但这一次当我从终端运行 PyQt5 程序时 它们没有显示任何窗口 从atom runner运行时也有同样的问题 它甚至没有显示任何窗口 错
  • 如何将用户信息从登录页面传递到主页?

    Error An object reference is required for the non static field method or property User Picture 如何将用户信息从登录页面传递到主页 线上错误Pic
  • 如何在 DataTables 中使用 pdfhtml5 导出 标签

    我想导出 a 使用 DataTables 中的单元格内的标签或链接pdfhtml5 截至目前 该链接显示为纯文本 如何打印它 包括其格式 这是一个两步过程 Step 1 使用数据表exportOptions format函数将完整的 HTM
  • IRC河豚加密模式?

    我一直在用这个工具做一些测试 http crypto hurlant com demo CryptoDemo swf并尝试匹配从 Mirc Blowfish 获得的 Blowfish 结果 来自以前的 Fish secure us v1 3
  • 在远程 Linux 机器上编译 C++ - “检测到时钟偏差”警告

    我通过 PuTTY 和 WinSCP 连接到我大学的小型 Linux 集群 使用后者传输文件并使用前者编译和运行它们 到目前为止 我的工作是在大学实验室进行的 但今天我在家里做了一些工作 产生了一个有趣的警告 我上传了整个文件夹的内容 然后
  • 通用方法返回类型 - 编译错误[重复]

    这个问题在这里已经有答案了 鉴于此代码示例 class A public class TestGenerics private static
  • Chrome 在 HTTP 302 重定向时取消 CORS XHR

    看起来像根据CORS 规范 GET 和 POST 请求应透明地遵循 302 重定向 但 Chrome 正在取消我的请求 这是执行请求的 JS var r new XMLHttpRequest r open GET https dev mys
  • 带有空格的图像文件名

    我通过 php 扫描图像文件夹获取图像 URL 数组 某些图像文件名带有空格 空格后面的部分丢失了 例如 这个文件很好 http domain com folder blue sky png 这个文件会丢失sky png部分 http do
  • Django/Python 环境错误?

    当我尝试使用时出现错误syncdb python manage py syncdb 错误信息 File usr local lib python2 6 dist packages django conf init py line 83 in
  • 如何处理我不知道其类型的脚本?

    我的游戏使用各种不同的游戏模式 我想根据所选的游戏模式在场景开始时生成不同的 GameController 脚本 然后其他项目 例如 敌人 将引用主 GameController 无论是 GameController Mode1 GameC
  • Angular Material2 md-select 下拉列表出现在页面底部

    我目前正在 Angular 2 4 0 应用程序中使用 Angular Material2 使用 angular material 2 0 0 beta 1 由于某种原因 md select 下拉列表没有出现在初始值或占位符或箭头上来选择下
  • 无法解析的日期

    我有一个字符串日期 31 Dec 和模式 dd MMM 以及下一个代码 DateFormat formatter new SimpleDateFormat pattern formatter setTimeZone timeZone for
  • VBA 中的 LinEst 函数可以使用数组吗?

    基本上 我不是从单元格中选择一个范围 而是通过使用循环将值存储在数组中 我理想中想做的是将这些数组用作 LinEst 函数中已知的 x 和 y 这样做的目的并不重要 因为我想做的只是我已经编写的代码的一部分 然而 Do 循环 至少是第二个
  • 在 r 中,获取功率曲线中“a”和“b”值的输出值

    我对这个基本问题表示歉意 但无论出于何种原因 我确实陷入困境 我希望从 y a x b 的 a 和 b 功率曲线中获得输出值 假设我有这个数据集 x y log10 x log10 y 7 240 0 84509804 2 38021124
  • 为什么 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?

    我有一个带有共享扩展的 iOS 应用程序 我正在尝试使用 NSUserDefaults 和应用程序组在它们之间共享数据 但是 虽然我可以写入 NSUD 对象 读取它 并且synchronize 没有错误 读取扩展名总是会导致nil 我有一个
  • PHP MySQL查询包含关键字/保留字[重复]

    这个问题在这里已经有答案了 我在更新 MySQL 数据 包括 HTML 数据 时遇到了问题 我不断修复错误 然而 一旦修正了一个错误 就会产生另一个错误 目前的错误如下 You have an error in your SQL synta
  • libipopt.so.1:无法打开共享对象文件

    执行基本安装后Ipopt 我能够编译他们提供的示例Ipopt 3 12 5 Ipopt examples hs071 cpp成功使用命令 g hs 071 main cpp hs071 nlp cpp I path to build inc
  • 从 F# 中的二叉搜索树中删除元素

    我正在尝试编写一种方法来从 BST 中删除元素 到目前为止 这就是我所拥有的 我不确定我是否走在正确的轨道上 或者是否有更好的方法通过使用模式匹配来匹配不同的删除情况 即 没有子项 1 个子项 2 个子项 type a bst NL Bin