Rust 中的基本树和指针

2024-04-24

我拥有一些 C 语言背景,尝试“学习”Rust 让我对自己的能力产生了质疑。我正在尝试找出如何更改拥有的指针,并且正在努力做到这一点。

除了从额外的库中复制之外,我无法弄清楚二叉树上所需的递归。特别是,我不知道如何交换指针分支。虽然使用链表我可以作弊并使用临时向量返回一个新列表,或者在列表头添加一个新的 Cons(value, ~Cons) ,但分支让我感到困惑。

enum NaiveTreeNode {
    NNil,
    NNode(~NaiveTreeNode, ~NaiveTreeNode, int, char) 
    //         left            right          key   val
}

impl NaiveTreeNode {
  fn eq(first_node: &NaiveTreeNode, second_node: &NaiveTreeNode) -> bool {
      match (first_node, second_node) {
          (&NNil, &NNil)              => true,
          ( &NNode( ~ref left_lval, ~ref left_rval, left_leafkey, left_leafval ),
            &NNode( ~ref right_lval, ~ref right_rval, right_leafkey, right_leafval )
          ) if left_leafkey == right_leafkey && left_leafval == right_leafval => {
              NaiveTreeNode::eq(left_lval, right_lval) && NaiveTreeNode::eq(left_rval, right_rval)
          },
          _                           => false
      }
  }

  fn add_branch(&mut self, node_to_add: ~NaiveTreeNode) {
      match (self, node_to_add) {
          (&NaiveTreeNode(~NNil, ~ref r_branch, leaf_key, leaf_val), ~NaiveTreeNode(_, _, new_node_key, _)              )
              if leaf_key > new_node_key   => self = &NaiveTreeNode(node_to_add, *r_branch, leaf_key, leaf_val),
          (&NaiveTreeNode(~ref l_branch, ~NNil, leaf_key, leaf_val), ~NaiveTreeNode(_, _, new_node_key, _))
               if leaf_key < new_node_key  => self = &NaiveTreeNode(*l_branch, node_to_add, leaf_key, leaf_val),
          (&NaiveTreeNode(~ref l_branch, _, leaf_key, _), ~NaiveTreeNode(_, _, new_node_key, _)) 
               if leaf_key > new_node_key  => self.add_branch(l_branch, node_to_add),
          (&NaiveTreeNode(_, ~ref r_branch, leaf_key, _), ~NaiveTreeNode(_, _, new_node_key, _)) 
               if leaf_key < new_node_key  => self.add_branch(l_branch, node_to_add),
          (_, ~NNil)                       => fail!("NNil branch. failing"),
          (&NNil, _)                       => fail!("NNil trunk. failing"),
          _                                => fail!("something is wrong. failing.")
      };
  }
}

编译器抛出了 11 个错误,当我输入它时,感觉就像是伪代码。我很沮丧,因为我觉得用 C 指针实现一棵树没问题。

我想做的是就地更新指针——这是我使用它们的部分原因,对吗?——而不是每次我想要进行更改时都复制整个树。但我什至不知道如何联系他们。

我不确定如何使用结构而不是枚举来完成此操作。我查看了 Treemap 库,但它似乎给我现在想要完成的任务带来了太多的复杂性,这是概念证明——不过,当我应该爬行时,我可能会尝试运行!


我相信使用不同的数据表示你会做得更好:

struct NaiveTreeNode {
    left: Option<~NaiveTreeNode>,
    right: Option<~NaiveTreeNode>,
    key: int,
    val: char,
}

这将更容易使用并且效率更高(Option<~T>可以表示为可空指针,而您当前的解决方案有一个叶节点仍然需要指针查找来检查它是否是NNil).

您不需要实施您的eq方法;它可以导出,一个实现Eq特质,通过把#[deriving(Eq)]紧接在结构之前。

Of your add_branch方法,你必须明白self.add_branch是一个绑定到的方法self。你打电话时self.add_branch(l_branch, node_to_add),这是无效的,因为您将两个参数传递给一个期望的参数。你的意思是l_branch.add_branch(node_to_add).

我已经重组了add_branch方法显着;这是我要编写的完整代码:

#[deriving(Eq)]
struct NaiveTreeNode {
    left: Option<~NaiveTreeNode>,
    right: Option<~NaiveTreeNode>,
    key: int,
    val: char,
}

impl NaiveTreeNode {
    fn add_branch(&mut self, node: ~NaiveTreeNode) {
        match (self.key.cmp(node.key), self.left, self.right) {
            (Greater, None, _) => self.left = Some(node),
            (Greater, Some(~ref mut left), _) => left.add_branch(node),
            (Less, _, None) => self.right = Some(node),
            (Less, _, Some(~ref mut right)) => right.add_branch(node),
            (Equal, _, _) => fail!("this tree already has a node with key {} \
                                    (value {}, attempted value {})", 
                                   self.key, self.value, node.value),
        }
    }
}

如果您愿意,匹配也可以扩展到以下内容:

        match self.key.cmp(node.key) {
            Greater => match self.left {
                None => self.left = Some(node),
                Some(~ref mut left) => left.add_branch(node),
            },
            Less => match self.right {
                None => self.right = Some(node),
                Some(~ref mut right) => right.add_branch(node),
            },
            Equal => fail!("this tree already has a node with key {} \
                                  (value {}, attempted value {})", 
                                  self.key, self.value, node.value),
        }

如果这段代码中有任何不明白的地方,请留言,我会解释的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rust 中的基本树和指针 的相关文章

  • Objective-C 中的二叉树

    我正在学习算法和数据结构 并尝试使用 Objective C 设计和实现二叉树进行训练 到目前为止 我有以下课程 main 供测试用 Node 树的节点 BinaryTree 对于与树相关的所有方法 最早的方法之一BinaryTree我实现
  • 使用递归求数组的最小值?

    好吧 所以我一直在尝试用 Java 来理解递归 我可以完成简单的任务 例如求和 反转等 但我一直在努力做这个练习 我试图使用递归找到数组中的最小数字 但始终得到 0 0 的答案 我对递归的理解是 我需要增加一个元素 然后提供一个结束递归的基
  • 使用记忆化与不使用记忆化的递归

    我在学校做的作业是用递归计算加泰罗尼亚数 第一个没有记忆 def catalan rec n res 0 if n 0 return 1 else for i in range n res catalan rec i catalan rec
  • 什么是二叉搜索树中的“内部节点”?

    我正在互联网上搜索 内部节点 一词的定义 我找不到简洁的定义 我正在查看的每个来源都使用该术语但没有定义它 并且这种用法并不能产生内部节点实际是什么的正确定义 这是我主要看的两个地方 Link https planetmath org Ex
  • 将字符串转换为个位数并求和

    我花了几个小时尝试寻找解决方案来完成我认为很简单的任务 但我失败了 我有一个由 3 个不同字符组成的字符串 I R O 长度从 1 到 6 E g IRRROO RRORRR IIR RIRRO 每个字符代表一个数字I 1 R 2 O 3我
  • 是否可以从 io::stdin() 读取字符而不逐行缓存输入?

    这个问题指的是稳定的Rust版本1 2 0 您可以通过使用单个字节数组并继续读取直到Result成为一个Err 然而 这有一个问题 因为如果您不以 ASCII 字符阅读 就会出现这种情况 如果您要遇到这个问题 最好只分配一个String 并
  • 预期关闭,发现不同的关闭

    A是一个包含向量的结构B A实施add b方法添加了一个B实例到列表B B包含一个闭包属性f 如果我添加一个B到向量add b 没关系 如果我将两个向量相加add b 我收到一个错误 说两个闭包不同 这是一个最小的例子 A struct s
  • Scipy:在对整个表面进行集成时加快集成速度?

    I have a probability density function pdf f x y And to get its cumulative distribution function cdf F x y at point x y y
  • 如何在 Rust 中删除字符串的第一个和最后一个字符?

    我想知道如何删除 Rust 中字符串的第一个和最后一个字符 Example Input Hello World Output ello Worl 您可以使用 chars 迭代器并忽略第一个和最后一个字符 fn rem first and l
  • Java 中的递归回溯解决填字游戏

    我需要在给定初始网格和单词的情况下解决填字游戏 单词可以多次使用或根本不使用 初始网格如下所示 这是一个单词列表示例 pain nice pal id 任务是填充占位符 水平或垂直长度 gt 1 像那样 p pain pal id i c
  • 是否有替代方法或方法让 Rc> 限制 X 的可变性?

    use std rc Rc use std cell RefCell Don t want to copy for performance reasons struct LibraryData Fields Creates and muta
  • 如何根据操作系统系列拥有不同的依赖关系

    我正在编写一个跨平台库 它具有特定于平台的依赖关系 一个用于类 UNIX 平台 一个用于 Windows 这些板条箱仅在特定平台上编译 因此我不能正常地将它们全部添加到依赖项下 在我实际使用的 Rust 代码中cfg属性 例如 cfg un
  • 为什么这个记忆器适用于递归函数?

    我不明白为什么下面的代码是这样的fib以线性而非指数时间运行 def memoize obj Memoization decorator from PythonDecoratorLibrary Ignores kwargs cache ob
  • 是否可以在纯 Rust 宏中编写像“print!”这样复杂的东西?

    我开始学习 Rust 宏 但文档有些有限 这很好 我想它们是一个专家功能 虽然我可以进行基本的代码生成 特征的实现等 但一些内置宏似乎远远超出了这些 例如各种打印宏 它们检查字符串文字并将其用于代码扩展 我在看的来源print https
  • 仅给出后序构造完整二叉树?

    我正在尝试构建一个完整的二叉树 完整的意思是每个非叶节点都有两个叶节点连接到它 即node gt right and node gt left are NULL 仅给出树的后序遍历 另外 我还知道后序遍历中的节点是否是叶节点 给定的后序遍历
  • 生成总和为 N 的所有数字排列

    我正在编写一个程序来创建所有数字 起初 我尝试使用分区函数对数字进行分区 然后对每个数字集进行排列 但是我认为这行不通 最好的方法是递归排列 同时对数字求和 这超出了我的能力范围 抱歉 如果这听起来真的很愚蠢 但我真的不知道 Example
  • 如何在 O(n) 时间内遍历二叉树而不需要额外的内存

    给定一棵带有整数 左指针和右指针的二叉树 如何在 O n 时间和 O 1 额外内存 无堆栈 队列 递归 内遍历该树 This guy http nandacumar blogspot com 2006 06 traversing tree
  • 泛型函数的不同实例是否可以具有不同的静态变量?

    当我在泛型函数中使用静态变量时 泛型函数的每个实例中的变量实体都是相同的 例如 在这段代码中 fn foo
  • 如何匹配特质实现者

    我有一个由某些结构实现的特征 我想编写一个模式匹配 可以处理每种可能的情况 trait Base struct Foo x u32 struct Bar y u32 impl Base for Foo impl Base for Bar f
  • 如何使用生成器遍历文件系统?

    我正在尝试创建一个实用程序类来遍历目录中的所有文件 包括子目录和子子目录中的文件 我尝试使用发电机 因为发电机很酷 然而 我遇到了困难 def grab files directory for name in os listdir dire

随机推荐

  • JavaScript Blob 对象何时被垃圾回收?

    在现代浏览器中 可以将大对象分配为Blob 然后通过 URL 请求访问它 此 URL 将在浏览器的其他位置提供存储的对象 例如图像的数据 浏览器如何知道何时不再需要这个 URL 以及相应的Blob数据可以免费被垃圾收集吗 浏览器最终将清除该
  • 如何在每次读取时更新配置?

    所以我有这样的课程 import yaml class Config def init self filename self config filename filename def read config file self with o
  • A-Frame:如何在 _blank 页面中打开动态创建的 a-link

    这是 A 型框架特有的 我正在从 javascript 代码创建一个 a link var alinkEl document createElement a link alinkEl setAttribute href http www f
  • PHP GD - 水平居中对齐文本并减小字体大小以将其保留在图像内

    希望你过得很好 我仍然是 php 的新手 所以在阅读了一些内容并检查了一些帖子之后 我能够使用 PHP GD 使用 imagecreatefrompng 函数在图像上放置一些文本 用户将进入一个表单 他们将能够输入他们的名字 并且名字将写在
  • Redux 调度导致组件本地状态重置

    我将 Redux 与 React 结合使用 我在用着this state 组件本地状态 保存组件特定变量 问题是 每当我调度操作 获取操作 和存储更新 安装 时 我的组件状态都会重置为初始状态 这对我的组件来说是正确的行为吗 第二次安装 重
  • Visual Studio 2012 中用户定义的 natvis 文件

    我正在尝试在我的项目中使用新的调试可视化工具 但 Visual Studio 发生了一些问题 它不再获取我的 natvis 文件 我尝试将它们复制到 USERPROFILE My Documents Visual Studio 2012 V
  • 错误请求 - 无效主机名 IIS7

    当我尝试在端口 8080 上访问我的网络应用程序时 出现以下错误 错误请求 无效主机名HTTP 错误 400 请求主机名无效 我什至不知道从哪里开始诊断这个问题 你检查一下绑定的是IIS吗 inetmgr exe 可能无法注册以接受 808
  • 在backbone.js 中缓存集合?

    确保我的集合保持缓存并仅获取一次的最佳方法是什么 我应该实现某种缓存层吗 我应该分享Collection变量到需要的地方 我可以信任 jQuery 的 AJAX 设置吗 ajaxSetup cache true 现在看起来的基本集合 the
  • 剪贴板大小限制

    复制到剪贴板的数据大小是否有限制 我正在使用 VB6 需要将数据块复制到剪贴板 应用程序调用GlobalAlloc GMEM MOVEABLE or GMEM DDESHARE 为要存储在剪贴板上的数据分配内存并使其可供其他应用程序使用 对
  • 如何在 R 中使用 dplyr “在事件之前”创建条件虚拟对象?

    我正在尝试使用规则创建条件虚拟 X 如果 NA 之前的最后两年 Y 1 则设置 X 1 仅计算一次 举个例子 这是我的数据中的一个样本 year country Y 1990 Bahamas 1 1991 Bahamas NA 1992 B
  • 如何在 WPF 中为用户控件创建用户定义(新)事件?一个小例子

    我有一个UserControl我正在其中使用Canvas 并在该画布中创建一个矩形 我想为该用户控件 画布和矩形 创建一个单击事件 然后我想在主窗口中使用它 问题是 我想为UserControl 怎么做 请展示一些例子或代码 A brief
  • 如果 vbs 脚本崩溃,请重新启动它

    我正在尝试制作一个 vb 脚本 如果它崩溃 它将重新启动另一个 vb 脚本 我搜索了又搜索 但我得到的只是如何重新启动程序 并且由于 vb 脚本是后台进程 因此当您在 Win32 Process 中搜索时它不起作用 这是我的代码 set S
  • 为 ARM 交叉编译 zlib

    我尝试为arm poky linux gnueabi交叉编译zlib 但启动 make 时出现错误 zlib 1 2 11 AR HOST ar CC HOST gcc RANLIB HOST ranlib configure prefix
  • 为什么最好使用 Glib 数据类型(例如 `gint` 而不是 `int`)? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么glib要重新定义类型 https stackoverflow com questions 1819561 why does glib redefine types 在 GTK 2 0 教程中
  • 用于计算机安全的遗传算法[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在为大学选择项目 我对遗传算法和计算机安全的结合非常感兴趣 因此我的问题是 是否可以使用GAany计算机安全方面 例如 我正在考虑
  • Chrome 浏览器在从 selenium 加载后立即关闭

    我正在运行一个基本的 python 程序来打开 Chrome 窗口 但是一旦代码执行 该窗口就会在那里停留一秒钟 然后立即关闭 from selenium import webdriver import time browser webdr
  • 如何组合杜松子酒中的路线组? [复制]

    这个问题在这里已经有答案了 我创建了两个不同的组gin具体路由 user and todo在两个不同的包中 我想将它们合并到一个文件中 这是我的userroutes go file package userrouter import git
  • 为复合对象编写比较器以进行二分搜索

    我有一个类和实例列表 看起来像这样 字段名称已更改以保护无辜 专有 public class Bloat public long timeInMilliseconds public long spaceInBytes public long
  • 使用 3DES 和 CBC 损坏的加密数据的前 8 个字节

    我在应用程序中使用 PyCrypto 来加密数据 但由于某种原因 无论我做什么 前 8 个字节 对应于第一个块 都会损坏 gt gt gt from Crypto Cipher import DES3 gt gt gt from Crypt
  • Rust 中的基本树和指针

    我拥有一些 C 语言背景 尝试 学习 Rust 让我对自己的能力产生了质疑 我正在尝试找出如何更改拥有的指针 并且正在努力做到这一点 除了从额外的库中复制之外 我无法弄清楚二叉树上所需的递归 特别是 我不知道如何交换指针分支 虽然使用链表我