从 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# 中的二叉搜索树中删除元素 的相关文章

随机推荐

  • 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