为淘汰赛创建二叉树

2024-01-08

我正在尝试创建一个用于淘汰赛的二叉树。该树由带有左指针和右指针的 TNode 组成。

这是我想出的代码(如下);然而,它在使用指针时遇到了困难CreateTree部分。

一旦创建了一个足够大的空树,我需要将 Memo1.List 上的名称添加到树的底部,以便我可以将它们配对以进行匹配。

我该怎么做?

Type
    TNodePtr = ^TNode;
    TNode = Record
        Data:String;
        Left:TNodePtr;
        Right:TNodePtr;
    end;
Type
    TTree = Class
    Private
        Root:TNodePtr;
    Public
        Function GetRoot:TNodePtr;
        Constructor Create;
    end;

var
  MyTree:TTree;


function TTree.GetRoot: TNodePtr;
begin
    Result:=Root;
end;

Constructor TTree.Create;
Var NewNode:TNodePtr;
Begin
    New(NewNode);
    NewNode^.Data:='Spam';
    NewNode^.Left:=Nil;
    NewNode^.Right:=Nil;
End;

Function Power(Base:integer;Exponent:integer):Integer;  //Used for only positive powers in this program so does not need to handle negatives.
begin
        If Base = 0 then
                Power := 0
        else If Exponent = 0 then
                Power := 1
        else //If Exponent > 0 then
                Power:=Base*Power(Base, Exponent-1);
end;

Function DenToBinStr(Value:Integer):String;
Var iBinaryBit:integer;
    sBinaryString:String;
Begin
    While Value <> 0 do
        begin
        iBinaryBit:=Value mod 2;
        sBinaryString:=sBinaryString+IntToStr(iBinaryBit);
        Value:=Value div 2;
        end;
    Result:=sBinaryString;
end;

Procedure TForm1.CreateTree;
    Var iRounds, iCurrentRound, iTreeLocation, iNodeCount, iMoreString, iAddedStringLength, iStringTree:Integer;
            sBinary:String;
            NewNode, ThisNode:TNodePtr;
    begin
            iRounds:=0;
            While Power(2,iRounds) < Memo1.Lines.Count do       {Calculates numbers of rounds by using whole powers of 2}
                    iRounds:=iRounds+1;
            If iRounds > 0 then {Make sure there IS a round}
            begin
                For iCurrentRound:=1 to iRounds do     {Select the round we are currently adding nodes to}
                begin
                    iTreeLocation:=Power(2,iCurrentRound);      {Works out the number of nodes on a line}
                    For iNodeCount:= 0 to iTreeLocation do       {Selects the node we are currently working on}
                    begin
                        ThisNode:=MyTree.GetRoot;
                        sBinary:=DenToBinStr(iNodeCount);           {Gets the tree traversal to that node from the root}
                        If Length(sBinary) < iCurrentRound then  {Makes sure that the tree traversal is long enough, Fills spare spaces with Left because 0 decimal = 0 binary (we need 00 for 2nd round)}
                        begin
                            iMoreString:= iCurrentRound-Length(sBinary);
                            for iAddedStringLength := 0 to iMoreString do
                                sBinary:='0'+sBinary;
                        end;
                        iStringTree:=0;                            {Init iStringTree, iStringTree is the position along the binary string (alt the position down the tree)}
                        While iStringTree <= iCurrentRound-1 do    {While we are not at the location to add nodes to, move our variable node down the tree}
                        begin
                            If sBinary[iStringTree]='0' then
                                ThisNode:=ThisNode^.Left
                            else If sBinary[iStringTree]='1' then
                                ThisNode:=ThisNode^.Right;
                            iStringTree:=iStringTree+1;
                        end;
                        New(NewNode);                           {Create a new node once we are in position}
                        NewNode^.Data:='Spam';
                        NewNode^.Left:=Nil;
                        NewNode^.Right:=Nil;
                        If sBinary[iCurrentRound]='0' then      
                            ThisNode^.Left:=NewNode
                        else If sBinary[iCurrentRound]='1' then
                            ThisNode^.Right:=NewNode;
                        ThisNode.Data:='Spam';
                        Showmessage(ThisNode.Data);
                    end;
                end;
            end;
    {1.2Add on byes}
    {1.2.1Calculate No Of Byes and turn into count. Change each count into binary
     equivalent then flip the bits}
    //iByes:= Memo1.Lines.Count - Power(2,iRounds);
    {1.2.2Add node where 0 is left and 1 is right}

    {2THEN FILL TREE using If node.left and node.right does not exist then write
     next name from list[q] q++}
    {3THEN DISPLAY TREE}
    end;

考虑通过从叶子构建树来完全不同地构建树。如果您有一个节点队列,则可以从前面取出两个节点,将它们与一个新节点连接在一起,然后将该新节点添加到队列的末尾。重复此操作,直到用完节点,您将获得一个锦标赛分组,其轮数与尝试从根部构建树所获得的轮数相同。

这是构建树的代码and用备忘录中的名字填充叶子。

var
  Nodes: TQueue;
  Node: PNode;
  s: string;
begin
  Nodes := TQueue.Create;
  try
    // Build initial queue of leaf nodes
    for s in Memo1.Lines do begin
      New(Node);
      Node.Data := s;
      Node.Left := nil;
      Node.Right := nil;
      Nodes.Push(Node);
    end;

    // Link all the nodes
    while Nodes.Count > 1 do begin
      New(Node);
      Node.Left := Nodes.Pop;
      Node.Right := Nodes.Pop;
      Nodes.Push(Node);
    end;

    Assert((Nodes.Count = 1) or (Memo1.Lines.Count = 0));
    if Nodes.Empty then
      Tree := TTree.Create
    else
      Tree := TTree.Create(Nodes.Pop);
  finally
    Nodes.Free;
  end;
end;

该代码的好处在于,我们在任何时候都不知道或关心任何特定节点需要处于什么级别。

如果参赛者的数量不是2的幂,那么名单末尾的一些参赛者可能会获得“轮空”回合,他们将被安排与名单顶部的获胜者进行比赛。上面的代码具有最少数量的节点。您的代码可能有许多“垃圾邮件”节点,这些节点并不代表锦标赛中的任何实际比赛。

树对象应该拥有它所包含的节点,因此它应该有一个析构函数,如下所示:

destructor TTree.Destroy;
  procedure FreeSubnodes(Node: PNode);
  begin
    if Assigned(Node.Left) then
      FreeSubnodes(Node.Left);
    if Assigned(Node.Right) then
      FreeSubnodes(Node.Right);
    Dispose(Node);
  end;
begin
  FreeSubnodes(Root);
  inherited;
end;

您会注意到我也更改了树的构造函数的调用方式。如果树是空的,则不需要任何节点。如果树不为空,那么我们将在创建它时为其提供节点。

constructor TTree.Create(ARoot: PNode = nil);
begin
  inherited;
  Root := ARoot;
end;

如果你有机会copy一棵树,那么您还需要复制它的所有节点。如果不这样做,那么当您释放一棵树时,副本的根节点指针将突然变得无效。

constructor TTree.Copy(Other: TTree);
  function CopyNode(Node: PNode): PNode;
  begin
    if Assigned(Node) then begin
      New(Result);
      Result.Data := Node.Data;
      Result.Left := CopyNode(Node.Left);
      Result.Right := CopyNode(Node.Right);
    end else
      Result := nil;
  end;
begin
  inherited;
  Root := CopyNode(Other.Root);
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为淘汰赛创建二叉树 的相关文章

  • 如何使 StringGrid 的列适合网格的宽度?

    我已经寻找解决方案很长时间了 但没有任何运气 有谁知道一个简单的方法来做到这一点 例如 我想拉伸网格的第二列以适应网格的宽度 Use the ColWidths财产 像这样 with StringGrid1 do ColWidths 1 C
  • 生成二叉树的所有从根到叶的分支

    抱歉 如果这是一个常见问题 但我还没有找到适合我的特定问题的答案 我正在尝试实施一个walk方法将二叉树从根节点遍历到每个叶节点 每当到达叶节点时都会生成根到叶路径 例如 遍历表示为的二叉树 a b d c 会产生 a b c a d 我的
  • 如何在iOS的Delphi程序中使用IPv6协议

    我尝试在我的移动程序中使用 IPv6 协议 我的服务器位于 NAT 后面的 LAN 内 在服务器上我使用IP端口3000 我已经组织了从路由器端口 45500 到服务器端口 3000 的虚拟服务器 端口转发 在服务器上 我运行 ipconf
  • 从 Delphi VCL 样式获取特定字形

    我想从 VCL 样式获取特定的位图 并将其设置为按钮上的图像 它实际上是帮助问号 在位图样式编辑器中是来自表单的 btnHelp 图像 要从 VCL 样式获取视觉元素 字形 您必须使用GetElementDetails和TCustomSty
  • 将图像加载到 TImageList 并读取它们?

    我试图通过将 jpg 转换为 bmp 然后将其保存到 imagelist1 来将 jpg 加载到图像列表中 从上到下的代码片段 Selectdir 有效 fileexists 部分有效 这用于加载文件夹中的所有图像 所有图像都以 0 jpg
  • logback的“谨慎模式”是如何实现的?

    The 审慎模式 http logback qos ch manual appenders html prudentlogback 中的序列化所有 JVM 之间的 IO 操作 写入同一文件 可能运行在不同的主机上 在其他日志记录框架中 如果
  • Delphi 中表单分发与其生命周期相关的接口对象的安全方法?

    我有一个 Delphi 表单 它提供接口对象背后的功能 代码的其他部分也通过属于该表单的属性获取引用 我无法将接口功能委托给子对象 因为太多的功能是由表单上的控件 组件提供的 我无法使用 TAggregateObject 或 TContai
  • 如何读取和更改 TEdit 控件的值?

    我有一个表格TForm1有 5TEdit and 2 TBitBtn 我还需要该程序 以便在输入数字数据后Edit1 and Edit2 on BitBtn1Click Edit1 and Edit2值将被求和并显示在Edit3 你想做这样
  • FireMonkey iOS RAD Studio XE2 - 在从 URL 加载的表单上显示图像

    是否可以将 TImage 放置在 iOS 的 FMX 表单上 并将图像 jpg 从 URL 加载到此 TImage 中以在 iOS 应用程序中显示 我尝试过但没有成功 任何正确方向的提示或指出都会受到赞赏 将 TButton TImageC
  • 似乎有时 Delphi 是区分大小写的 - “覆盖方法应该与祖先的大小写匹配”

    今天我遇到了一个 奇怪 的提示 覆盖方法 xxxx 应匹配祖先 yyyy 的大小写 解决方案是完全按照祖先中的方式声明方法名称 我相信这是自 Delphi Net 编译器以来编译器中保留的东西 与祖先中完全相同的方法声明方法使编译器 沉默
  • FireDac 添加下划线 1 以区分具有相同名称的 2 个列名

    我有一个连接 2 个表的选择 因此这些表中存在具有相似名称的列 因此现在在检索结果时 FireDac 将下划线 1 添加到第二个列名称以区分这两个表 Select from Table1 inner join Table2 on Table
  • 使用 Delphi 10.2.1 Tokyo 的模态 Android 对话框

    我有以下用于在 Android 上显示模式消息的 Delphi 代码 该代码在 10 1 Berlin 上运行良好 但在 Delphi 10 2 1 Tokyo 上停止运行 此过程现在会挂起 Android 应用程序 procedure c
  • Delphi + Synapse:如何检查我是否仍然连接

    我在用TTCPBlockSocket http synapse ararat cz doc help blcksock TTCPBlockSocket html对于 TCP IP 应用程序 问题是我无法确定连接何时丢失 GetLastErr
  • 如何修复这个 delphi 7 编译错误 - “重复资源”

    我正在尝试编译我继承的 Delphi 7 项目 但收到此错误 错误 警告 重复资源 错误 类型 2 位图 ID 编辑 错误 文件 C 路径缩短 common CRGrid res 资源已保留 文件 c common raptree RES
  • Delphi - 如何使用 iPhone 作为图片源通过 OpenDialog 获取目录

    我有一个 Delphi 应用程序 D2010 它允许用户通过 OpenDialog 选择 JPG 文件 当我从普通 Windows 目录中选择文件时 我的 TOpenDialog Filename 包含该文件的完整路径 并且我的代码可以正常
  • 在 Inno Setup 中使用 {AppVersion} 作为函数的参数

    所以我有一个正在更新一些 XML 的函数 我想传递 AppVersion 已设置在 Setup 脚本的一部分作为该函数的常量 我努力了 MyFunction ExpandConstants AppVersion 但这给了我一个错误 如何正确
  • 德尔福和Doxygen

    我想使用 doxygen pas2dox 记录我的源代码 当我设置好所有内容 包括过滤器和提取选项 提取所有内容 时 doxygen 运行良好 但生成的文档仅包含源文件作为链接 并且没有提取类型 方法 过滤后的源看起来不错 有任何提示如何定
  • VirtualStringTree 正确/推荐使用

    我已经使用 virtualstringtree 一段时间了 我将它用于两个不同的用途 第一个是用于选择 显示数据的普通树 第二个是作为网格来显示 SQL 语句的输出 我加载到树中的所有数据都来自数据库 对于树示例 我有一个 ParentId
  • Soap Delphi 客户端因 1MB 调用超时而结束

    我们正在开发 SOAP Web 服务 Apache PHP 所有小规模调用都运行良好 但对于 1Mb 的 Soap 调用 HTTPS 调用大小为 1MB 我们的 Delphi Soap 客户端在除一台 PC 之外的所有 PC 上都因超时而停
  • Delphi 是否在构造对象之前分配变量?

    Delphi 是否在对象完全构造之前分配实例变量 换句话说 给定一个变量 var customer TCustomer nil 然后我们构造一个客户并将其分配给变量 customer TCustomer Create 有没有可能custom

随机推荐

  • Hibernate:仅在不存在时才创建数据库[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想要 Hibernate 创建数据
  • groovy 中的闭包与 java 8 中的闭包(lambda 表达式)?

    Given doSomething Function foo println foo 2 Groovy doSomething it it as Function Java doSomething x gt x x 两者有什么区别吗 在 G
  • 在 parmap 上使用 pyinstaller 会导致 tkinter matplotlib 导入错误。为什么?

    Update 如果我尝试从 Pyinstaller 3 2 降级到 3 1 当我尝试运行可执行文件时 我会得到以下回溯 我尝试添加 hidden import collect submodules pkg resources vendor
  • 使用 React 和 Material UI 的全局样式

    我是 React 和 Material UI 的新手 但我必须编写一个具有漂亮样式的企业应用程序 我想为我的应用程序使用某种全局样式 以便稍后能够更改它 与react中的功能组件 也许我稍后会添加redux 使用 React 和 Mater
  • VBA 矩阵乘法 MMult

    我正在努力解决 运行时错误 1004 无法获取 WorksheetFunction 类的 MMult 属性 我使代码尽可能简单 但它仍然不起作用 如果有提示 我将不胜感激 Sub Matrix Computation3 Dim ws3 As
  • 使用类型转换运算符

    我有一个 Visual Studio 2008 C 应用程序 我需要从采用可变大小缓冲区的函数中获取信息 所以 我有一个类支持该类型std vector并实现一个转换运算符到我想要的类型 class CMibIpForwardTable p
  • 标识符“n”未定义,“对象”不包含这样的成员

    Visual Studio Code 1 17 0 生成错误Angular当我处理来自不在基类上的继承类型的成员并且基类在组件上声明时 模板 在下面的代码中 显然maxLength不存在于QuestionBase 但是我该怎么办呢 Angu
  • 无法在 webpack-dev-server 中查看请求日志

    我在用webpack dev server在本地充当 CDN 服务器来提供各种静态资源 如 css js html 等 一切运行正常 但出于调试目的 我无法看到 CDN 服务器收到的请求 webpack dev server一旦编译了静态资
  • 如何在 Rust 1.12 中检查 read_line 中的 EOF?

    考虑以下程序 如何检测 stdin 中的 EOF 并打破循环 use std io use std process fn main let mut sum 0 loop let mut number str String new match
  • 如何覆盖按钮点击角度的测试? (Stackblitz附后)

    我正在制作一个非常简单的应用程序 它有一个输入框和一个按钮 输入用于输入email 订阅button与事件处理程序 输入电子邮件并单击按钮将进行 api 调用 此方法有效 subscribeEmail this error if this
  • 如何在Spring中将文件夹的所有文件加载到资源列表中?

    我有一个文件夹 想要使用 Spring 和通配符将所有 txt 文件加载到列表中 通过注释我可以执行以下操作 Value classpath dir txt private Resource files 但是我怎样才能以编程方式使用 spr
  • RGB 与 HLS 之间的转换

    我正在使用 python 的 colorsys 库将 RGB 颜色值转换为 HLS 为了验证一下 我尝试转换回 RGB 并得到了不同的值 我可以理解由于精度问题而产生的微小差异 但这些值有很大不同 这是我的代码 import colorsy
  • django原始查询百分号问题

    我尝试在 Django 中进行原始 sql 查询like函数 但结果为空 我尝试mysql客户端工具这个查询并得到很多记录 如何解决这个问题 我的查询 SELECT s s id as pk FROM d status as s selec
  • 查询 google play 商店的应用程序版本?

    有没有一种方法可以在游戏商店中查询应用程序的版本 而无需用户凭据 我知道这个非官方 API http code google com p android market api http code google com p android m
  • iPhone SDK 中“ ”(空格)的转义序列是什么?

    在我的 iPhone 应用程序中 我有一个 ASCII 艺术 两个字符之间有很多空格 所以我需要添加空格的转义序列来代替每个空格 iPhone SDK 中的空格转义序列是什么 您可以使用不间断空格 http en wikipedia org
  • AWS CodeBuild buildspec.yml 递归获取所有文件和子文件夹

    我正在尝试使用 AWS CodeBuild 获取嵌套内的所有文件和子文件夹public文件夹并使用 CodePipeline 部署到 S3 存储桶 我能够将它们全部连接在一起 但很难配置buildspec yml文件以获得我想要的输出 我的
  • Rcpp 和 CULA:分段错误

    我从以下内容中提取了相关位GPU工具R 用于在我的 GPU 上运行 QR 分解的包Rcpp通过动态加载链接到的共享库库拉工具 航站楼内一切顺利R app在我的 Mac 上 结果符合R s qr 函数 但问题是退出时发生分段错误R app 使
  • 使用 Hibernate 注解映射枚举类型

    我的 Java 模型上有一个枚举类型 我想将其映射到数据库上的表 我正在使用 Hibernate Annotations 但我不知道该怎么做 由于我搜索的答案相当旧 我想知道哪种方式最好 提前致谢 除了这个之外你还需要其他东西吗 Enume
  • clusterExport、环境和变量范围

    我编写了一个函数 在其中定义变量并加载对象 这是一个简化版本 fn1 lt function x load data RData a vector named data source myFunctions R library raster
  • 为淘汰赛创建二叉树

    我正在尝试创建一个用于淘汰赛的二叉树 该树由带有左指针和右指针的 TNode 组成 这是我想出的代码 如下 然而 它在使用指针时遇到了困难CreateTree部分 一旦创建了一个足够大的空树 我需要将 Memo1 List 上的名称添加到树