如何从二叉搜索树中均匀随机地返回节点?

2024-05-10

给定一个 BST(可能平衡也可能不平衡),如何能够均匀地随机返回“任何”节点?一个限制是您不能使用外部索引数据结构。您必须以每个节点都有平等被访问的机会的方式遍历树。

这个问题让我困惑了好一阵子。如果我们确实可以使用外部哈希表/指针,我们可以对它们进行随机化并返回相应的节点。然而,我的同事提出了这个问题的一个相当复杂的变体,其中不能使用额外的数据结构。

  • 具有 50-50 概率进入 L/R 的简单随机游走不起作用,因为返回靠近树底部的节点的概率要小得多(概率复合)
  • 甚至随机生成深度d并且最多遍历d节点返回节点(如果是叶子则停止)不会生成均匀分布。

Update:您也不能进行中序遍历并将结果存储在数组中。

如何才能实现这样的穿越呢?


以任意顺序遍历树,并保留以下值:

  • N:看到的节点数

  • selected:当前选择的节点。

最初,N是 0 并且selected is None。访问节点包括以下内容:

  1. 增量N

  2. 生成范围内的随机整数[0, N).

  3. 如果选择的随机整数为0,则设置selected到当前节点。

请注意这些值N and selected需要在行走过程中进行修改。这意味着它们都是访问者函数的输入值和输出值。

步行结束时,N将是树中的节点数,并且selected将是以均匀概率选择的随机节点(假设您有一个好的随机数生成器)。

该算法不限于 BST。它适用于任何形状的任何树。特别是,它将处理未知长度的简单线性对象序列,对应于众所周知的随机选择算法,即迭代对象,以概率用新访问的对象替换所选的随机对象1/N where N是迄今为止看到的物体数量。

如果您跟踪访问过的节点,它也适用于任何连通图。

如果您有一个非常大的树(或图),可能分布在许多服务器和/或存储设备上,您可以使用此算法的不同表示形式,这提供了一定程度的并行性(并且还避免了需要保持全局步行结构或将值传递到步行中)。

我们假设每个节点服务器都可以直接访问k对象和间接访问某些已知数量的子服务器。该算法允许冗余子节点,但假设网络通信(几乎)完美;处理网络分裂超出了本答案的范围。我们还假设每个查询都有一个关联的唯一查询号,这使我们能够处理一些网络工件。该查询没有其他信息(除了要响应的服务器之外),并且预计返回一个由计数和随机选择的节点组成的元组。

当节点服务器收到带有 id 的查询时q,它执行以下操作:

  1. 如果它之前已响应过查询q,立即返回<0, null>

  2. Set count to k and selected到一个随机选择的对象k它可以直接访问的对象。

  3. 对于每个子服务器,发送查询(具有相同的查询 ID)

  4. 对于返回的每个响应(响应的顺序并不重要):

    a. Add response.count to count

    b.有概率response.count / count, 代替selected with response.selected

  5. 当所有子服务器响应后,返回<count, selected>

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

如何从二叉搜索树中均匀随机地返回节点? 的相关文章

  • 如何确定算法函数的复杂度?

    您如何知道算法函数对于特定操作是否需要线性 常数 对数时间 它取决于CPU周期吗 您可以通过三种方式 至少 做到这一点 在网上查找算法 看看它是如何描述其时间复杂度的 根据输入大小 自己检查算法 查看嵌套循环和递归条件等内容 以及每个循环运
  • 最慢的计算复杂度(Big-O)

    在这些算法中 我知道 Alg1 是最快的 因为它是 n 平方的 接下来是 Alg4 因为它是 n 的立方 然后 Alg2 可能是最慢的 因为它是 2 n 这应该具有非常差的性能 然而Alg3和Alg5在我的阅读速度方面还没有遇到过 这两种算
  • Karasuba算法递归过多

    我正在尝试用 c 实现 Karasuba 乘法算法 但现在我只是想让它在 python 中工作 这是我的代码 def mult x y b m if max x y lt b return x y bm pow b m x0 x bm x1
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • 生成所有多集大小为 n 的分区的算法

    我一直在试图找出一种方法来生成多重集的所有不同的大小为 n 的分区 但到目前为止却空手而归 首先让我展示一下我想要实现的目标 假设我们有一个输入向量uint32 t std vector
  • 快速约会算法

    我在一家咨询公司工作 大部分时间都在客户所在地 正因为如此 我很少见到同事 为了更好地了解彼此 我们将安排一个晚宴 会有很多小桌子 方便人们聊天 为了在聚会期间与尽可能多的不同的人交谈 每个人都必须每隔一段时间 比如每小时 换一张桌子 如何
  • 在常数空间中创建 1..N 的随机排列

    我正在寻找枚举固定空间中数字 1 N 的随机排列 这意味着我无法将所有数字存储在列表中 原因是 N 可能非常大 超过可用内存 我仍然希望能够一次遍历这样一个数字的排列 只访问每个数字一次 我知道对于某些 N 可以这样做 许多随机数生成器随机
  • 使用并集查找(又名不相交集)检测图是否是二分图

    我正在 Spoj 上做一个问题 基本上可以简化为检测图是否是二分图 我正在尝试使用 dfs 为图表着色 但它太慢了 有人评论这个 没有 bfs 没有 dfs 没有二部图 简单的并查集就可以做到 确实速度很快 提示 1 偶数长度的环不会影响两
  • 计算两点之间的最短路线

    过去几周我一直在开发一款多人 HTML5 游戏 使用nodejs and websockets 我已经被这个问题困扰了一段时间 想象一下 我用数组实现了这个平铺地图 如下所示 1 or 棕色瓷砖 路上有障碍物 玩家无法通过 0 or 绿色瓷
  • 如何检查是否存在可能的路径?

    我正在开发一个基于 javascript 的实验性游戏 玩家必须在二维平铺地图上移动才能退出 请随意检查这个小提琴并演奏 http jsfiddle net moonlife 74vLd 我只是随机放置障碍物 但有时障碍物会挡住玩家和出口之
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 找到一条穿过任意节点序列的最短路径?

    In 这个先前的问题 https stackoverflow com questions 7314333 find shortest path from vertex u to v passing through a vertex wOP询
  • 迭代任意大小的子集

    我可以迭代大小为 1 的子集 for int a 0 a lt size a 或大小为 2 的子集 for int a1 0 a1 lt size a1 for int a2 a1 1 a2 lt size a2 or 3 for int
  • 具有 2 个属性的背包算法。如何在 3d 数组中实现它?

    当有超过 1 个属性时 我无法理解背包问题 当有 1 个属性时 我必须编写一个使用具有 2 个属性的背包算法的程序 老师告诉我们 它必须在 3d 数组中完成 错误的实现将导致 O 2 n 处理时间 我无法想象这样的数组会是什么样子 假设这是
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • n 或 nlog(n) 比常数时间或对数时间更好吗?

    在 Coursera 上的普林斯顿教程中 讲师解释了遇到的常见增长顺序函数 他说 线性和线性算术运行时间是 我们努力的目标 他的推理是 随着输入大小的增加 运行时间也会增加 我认为这是他犯了错误的地方 因为我之前听过他提到线性增长顺序对于高
  • 每个术语出现的次数

    我得到了一个数组a n 2 where n can be 10 5最大时有n个科目和n个学生 全部编号为 1 2 n a i 0 and a i 1 1 lt i lt n 表示在第 i 个科目中 所有来自a i 0 to a i 1 通过
  • 二维滑动窗口最小值/最大值

    假设我们得到一个大小为 NxN 的像素整数矩阵和一个整数 k 窗口大小 我们需要使用滑动窗口找到矩阵中的所有局部最大值 或最小值 这意味着 如果某个像素与其周围窗口中的所有像素相比具有最小 最大 值 则应将其标记为最小 最大 有一种著名的滑
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex

随机推荐

  • 编译时和运行时转换 C#

    我想知道为什么 C 中的某些强制转换会在编译时进行检查 而在其他情况下则将责任转嫁给 CLR 如上所述 两者都是不正确的 但处理方式不同 class Base class Derived Base class Other static vo
  • 在应用程序启动期间更改主题的最快方法

    目前 我确实在我的应用程序中根据用户最后的选择提供了 2 个主题 深色主题和浅色主题 在主要活动启动期间 我将执行以下操作 public class MyFragmentActivity extends FragmentActivity O
  • C# 中的继承树和受保护的构造函数

    给定以下继承树 以有效的方式实现它的最佳方法是什么 abstract class Foo
  • bash 函数保留制表符补全

    我把函数 make color make 1 ccze A in bashrc获得彩色的 make 输出 他的作品很好 但是make用于选择目标的制表符补全功能丢失 有什么方法可以保留函数中命令的制表符完成 或者我可以做其他事情来实现制表符
  • 方法不必要地被调用?

    我有一个 BaseActivity 它可以通过其他所有活动进行扩展 问题是 每当用户离开 暂停 活动时 我都会将音乐静音 我也不再接听电话 问题是 onPause每当用户在活动之间切换时就会被调用 这意味着应用程序不必要地静音和停止tele
  • 如何从 JavaScript 触发 ASP.NET Core 客户端验证

    有没有办法从 JavaScript 触发 ASP NET Core 客户端验证 我有一个 Razor Pages 页面 其中包含
  • 从控制台应用程序隐藏控制台窗口[重复]

    这个问题在这里已经有答案了 我有一个使用控制台的应用程序 但我更改了所有代码以写入文件而不是控制台 我现在希望在运行应用程序时控制台停止出现 我该怎么做呢 我不知道是什么首先打开了控制台 即使代码中没有写入任何内容 我查看了应用程序引用 但
  • 同时调用多个支持 bean 方法

    有没有办法从 JSF 中的不同支持 bean 调用多个方法 我有一个存储用户信息的应用程序 我有多个支持 bean 它们分为时间表 地址 电话等 当应用程序最初加载时 一切正常 但由于我的所有视图都是类型 ViewScope即使显示新用户
  • Visual Studio退出调试,没有任何异常或错误

    我有一个TCP CLIENT游戏服务器项目在视觉工作室2010 当我在调试模式下启动项目时 需要一段时间 有时 1 天 有时 1 周 视觉工作室退出调试 没有任何异常或错误 我检查了窗口和应用程序日志 没有什么意外的 如何找出真正的问题是什
  • 生成的表的行跨度导致额外的单元格

    HTML table border 1 cellspacing 1 width 100 thead tr td class csstextheader width 70px td td class csstextheader width 7
  • jQuery 无法在外部 JavaScript 中工作

    我是 jQuery 新手 遇到了一些奇怪的问题 我正在使用 jQuery 的change and click方法 在我的 HTML 文件中使用时它们工作正常
  • Python 2.7 布尔运算符逻辑

    我目前正在学习Python 2 7 并且遇到了相等和布尔运算符 我的问题是 Why False and 1 is False but True and 1 is 1 同样地 False or 1 is 1 but True or 1 is
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • Visual Studio 2013删除已删除的git分支

    我遇到这个问题 在 VS2013 中 当我从源创建一个新分支时 源分支的下拉列表列出了曾经创建的所有分支 这包括长期从本地存储库和远程 源存储库中删除的分支 如何删除已删除的分支 Visual Studio 将它们保存在本地缓存中 您可以从
  • 提供软件设置的最佳方式?

    我正在使用 C NET 在我的软件中 我提供设置对话框 用户可以通过该对话框设置我想要保存到文件的应用程序设置 要求 典型 我定义的每个类都使用这些设置的某些部分 因此 这些对于所有类都应该是全局的 这些应该在软件启动时加载 当用户更改设置
  • 在 python 的 Visual Studio 工具中按下 ctrl+F5 后,控制台窗口立即关闭

    我已经安装了 Visual Studio 的 Python 工具 但在控制台窗口中看不到输出 就像我在 Visual Studio 中运行 C 控制台应用程序时按以下快捷键时看到的输出一样 F5 开始调试程序并关闭 C 和 Python 中
  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • 如何使用.net更改selenium中的用户代理

    我想使用不同的代理 iPhone iPad Android 测试用 NET 编写的 Web 应用程序 我使用 NUnit 和 Selenium 进行测试 有人有一个用 c 或 VB 在 Selenium 中更改代理 例如 iPad 或 iP
  • 如何使用 LeafLe 创建商店地图

    我希望创建一个可以交互的地图 我发现的最好的选择是传单 问题是我没有找到任何资源来解释如何创建自己的地图 我希望创建一个商场地图 用户可以在其中看到所有商店 喷泉 我怎样才能做到这一点 最好的起点是传单示例页面 http leafletjs
  • 如何从二叉搜索树中均匀随机地返回节点?

    给定一个 BST 可能平衡也可能不平衡 如何能够均匀地随机返回 任何 节点 一个限制是您不能使用外部索引数据结构 您必须以每个节点都有平等被访问的机会的方式遍历树 这个问题让我困惑了好一阵子 如果我们确实可以使用外部哈希表 指针 我们可以对