VST实例(5)节点(NODE) 二、节点的遍历

这篇具有很好参考价值的文章主要介绍了VST实例(5)节点(NODE) 二、节点的遍历。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

二、节点的遍历

每一个节点都有一个index值,用于描述其在相同level,相同父节点下的序号,但是,遍历时并不能利用这个值,因为这个值是变化的,当进行排序,插入节点、删除节点等等操作时,这个index会发生改变。

同样的,vst.AbsoluteIndex(node)返回的是某一节点在VST中的绝对序号,也会在排序等操作时进行改变。

1、通过函数遍历节点

下面这些函数可以找到特定的第一个的节点:

  •          function GetFirst(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetFirstChild(Node: PVirtualNode): PVirtualNode;
  •          function GetFirstCutCopy(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetFirstInitialized(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetFirstNoInit(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetFirstSelected(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetFirstVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True; IncludeFiltered: Boolean = False): PVirtualNode;
  •          function GetFirstVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True; IncludeFiltered: Boolean = False): PVirtualNode;

找下一个节点的函数有:

  •          function GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetNextChecked(Node: PVirtualNode; ConsiderChildrenAbove: Boolean): PVirtualNode;
  •          function GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetNextLeaf(Node: PVirtualNode): PVirtualNode;
  •          function GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
  •          function GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetNextSibling(Node: PVirtualNode): PVirtualNode;
  •          function GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
  •          GetNextVisible...,其它的针对可见NODE的查找下一个。

如果没有指定节点的下一个,则返回nil。

查找最后一个节点:

  •          function GetLast(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
  •          function GetLastChild(Node: PVirtualNode): PVirtualNode;
  •          function GetLastVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True; IncludeFiltered: Boolean = False): PVirtualNode;
  •          ……

下面的代码可以实现遍历:

var node:pvirtualnode;

……

begin

  node:=vst.getfirst;

  repeat

     ……

     node:=vst.getnext(node);

  until node=vst.getlast;

end;

 

当然,上面的代码中未包含对最后一个节点的处理。

2、遍历函数IterateSubtree

遍历函数的原型是:

function IterateSubtree(Node: PVirtualNode; Callback: TVTGetNodeProc; Data: Pointer; Filter: TVirtualNodeStates = []; DoInit: Boolean = False;

 

功能是对VST中的Node的每一个子(孙)节点进行一次回调函数(callback)的操作。如果回调函数返回了abord:=true,则终止遍历,并返回终止遍历的节点。

如果参数node=nil,则对所有的节点进行遍历。

data是传入回调函数的指针参数,而Filter是筛选器,如果为空,则对所有的节点进行遍历,否则只对具有筛选器状态的节点进行遍历。例如如果filter包含“vsvisible”,则只对可见的节点进行遍历。

回调函数的格式是:

TVTGetNodeProc = procedure (Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean) of object;

其中data指的就是IterateSubtree中指向的数据data。

以本程序为例,当编辑框中内容发生改变,则立即查找符合条件的节点,并设置为可见,不符合条件的节点则设置为不可见。

代码如下:

procedure TForm2.lbledt1Change(Sender: TObject);

var data:pchar;

begin

   data:=PChar(lbledt1.Text);

   //beginupdate之后的语句只有当遇到endupdate之后才进行显示刷新

   //可以避免程序的频繁刷新导致的抖动,加快程序的运行。

   vst.BeginUpdate;

   //调用遍历函数,传入的参数是文本框的文本

   vst.IterateSubtree(nil,getnodebystr,data);

   //让所有符合条件的节点展开

   vst.FullExpand();

   vst.EndUpdate;

end;

 

回调函数getnodebystr的定义和代码如下:

procedure GETNODEBYSTR(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);

……

procedure TForm2.GETNODEBYSTR(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);

var str1,str2:string;

begin

  str1:=string(Data).Trim.ToUpper;

  with pcodes(Sender.GetNodeData(node))^ do

  begin

    str2:=icao+'|'+iata+'|'+names;

  end;

  str2:=str2.Trim.ToUpper;

  if str2.Contains(str1) or str1.IsEmpty then

  begin

    Sender.FullyVisible[NODE]:=true;

    //下面部分是设置可见的另一种写法,如果不包含子节点,则效率会更高

    //sender.IsVisible[node]:=True;

    //if Sender.GetNodeLevel(node)>0 then//有父节点的情况下

    //  Sender.IsVisible[Node.Parent]:=True;

  end

  else

  begin

    Sender.IsVisible[node]:=false;

  end;

end;

 

本程序共有630个节点,在执行中完全可以实时查询无停顿。VST的效率非常高。

3、节点序列

前面我们提到过vst.SelectedNodes和vst.checkedNodes都是节点序列,节点序列的定义是这样的:

TVTVirtualNodeEnumeration = record

  objectprivateFMode: TVZVirtualNodeEnumerationMode;

  FTree: TBaseVirtualTree;

  FConsiderChildrenAbove: Boolean;

  FNode: PVirtualNode;

  FNodeLevel: Cardinal;

  FState: TCheckState;

  FIncludeFiltered: Boolean;

end;

 

并提供了一个函数:GetEnumerator,用于从FTREE中获取具有指定特征的节点,例如checkednodes就是从VST中取得具有某种TCheckState属性的所有节点,而SelectedNodes则是获得具有selected属性的节点(node的states属性),所以你也可以写自己的节点序列程序。

函数GetEnumerator返回的是一个TVTVirtualNodeEnumerator类型的结构(record),其具体使用代码例子如下:

var node:PVirtualNode;

begin

  with vst.CheckedNodes().GetEnumerator do

  begin

    MoveNext;

repeat

      node:=Current;

      ……

    until not MoveNext;

  end;

end;

 

需要注意的是,一定要针对GetEnumerator返回的结构进行操作,不能一次次的调用GetEnumerator.current 和GetEnumerator.movenext,因为每次调用一次GetEnumerator就会生成一次序列。

请注意,调用GetEnumerator后,current并没有对应某个NODE,需要调用一次movenext后,current才指向第一个node,每调用一次movenext,current指向下一个node,如果已经是最后一个node,调用movenext则返回false.

程序中写了一小段代码,用于把选中的机场资料导出到一个CSV文件中。

procedure TForm2.N5Click(Sender: TObject);

var sl:TStringList;s:string;

begin

  if vst.CheckedCount=0 then Exit;

  sl:=TStringList.Create;

  with vst.CheckedNodes(csCheckedNormal).GetEnumerator do

  begin

    MoveNext;

    repeat

       //如果是根节点,即FIR,则跳到下一个循环

       if vst.GetNodeLevel(current)=0 then  Continue;

       s:='';

       if Assigned(current) then

       with pcodes(vst.GetNodeData(current))^ do

       begin

         s:=s.Join(',',[icao,iata,names,rwy_style,apt_type]);

       end;

       sl.Add(s);

    until not MoveNext;

  end;

  //直接把文档存储到执行文件所在目录的文件中

  sl.SaveToFile('checkedapts.csv');

  FreeAndNil(sl);

end;

 文章来源地址https://www.toymoban.com/news/detail-463311.html

到了这里,关于VST实例(5)节点(NODE) 二、节点的遍历的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二叉树的遍历(节点个数及层序遍历)

     简易树的图形:    运行实例: 以A节点开始运算的节点个数 以B节点开始运算的节点个数 解释(图解+文字解释):  把A传过去A不为空,进入left,A的left为B不为空,B的left为D不为空,D的left和right都为空返回0+0+1,在进入B的right,B的right为E不为空,E的left和right都为空返回

    2023年04月22日
    浏览(53)
  • 算法(链表链表的创建、插入节点、删除节点、遍历节点及其长度)

                                  id:671593      转自:Hitsu 本人在idea中能够正常运行出来(结果3 3 2 1 4)。 链表的创建、插入节点、删除节点、遍历节点及其长度。 Java构建链表两种方式 第一种 (这一种写出来看起来更简洁) Java构建链表两种方式 第一种 (这一种写出来

    2024年02月13日
    浏览(35)
  • 二叉树详解(深度优先遍历、前序,中序,后序、广度优先遍历、二叉树所有节点的个数、叶节点的个数)

    目录 一、树概念及结构(了解)  1.1树的概念  1.2树的表示  二、二叉树概念及结构  2.1概念  2.2现实中的二叉树: 2.3数据结构中的二叉树: 2.4特殊的二叉树:  2.5 二叉树的存储结构  2.51 顺序存储:  2.5.2 链式存储: 三、二叉树性质相关选择题练习  四、二叉树的实现 4

    2024年02月03日
    浏览(44)
  • DOM 节点遍历:掌握遍历 XML文档结构和内容的技巧

    遍历是指通过或遍历节点树 通常,您想要循环一个 XML 文档,例如:当您想要提取每个元素的值时。 这被称为\\\"遍历节点树\\\"。 下面的示例循环遍历所有 book 的子节点,并显示它们的名称和值: 输出: 示例解释 将 XML 字符串加载到 xmlDoc 中 获取根元素的子节点 对于每个子节点

    2024年04月08日
    浏览(85)
  • LeetCode 2641. 二叉树的堂兄弟节点 II:层序遍历并记下兄弟节点

    力扣题目链接:https://leetcode.cn/problems/cousins-in-binary-tree-ii/ 给你一棵二叉树的根  root  ,请你将每个节点的值替换成该节点的所有 堂兄弟节点值的和  。 如果两个节点在树中有相同的深度且它们的父节点不同,那么它们互为 堂兄弟  。 请你返回修改值之后,树的根   root

    2024年02月20日
    浏览(43)
  • k8s添加node节点和master节点

    版本: kubelet:v1.20.4 docker: 20.10.23 资源: cpu:8 mem:16 kernel:3.10.0-1160.71.1.el7.x86_64 镜像仓库地址: registry.cn-hangzhou.aliyuncs.com/google_containers/ 2.1)关闭防火墙 2.2)关闭selinux 3)修改内核和加载所需要的内核 2.3)准备yum源 3.1)刷新缓存安装kubeadm、kubectl、kubelet、docker-ce 3.2)设置syste

    2023年04月16日
    浏览(51)
  • Jenkins 添加node节点

    安装SSH插件 Jenkins- 插件管理- 可选插件- 搜索SSH Agent 配置启用SSH Server Jenkins- 系统管理 - 全局安全配置, 把 SSH Server 设置为启用(默认是禁用) 新增节点 第一种方式(SSH密钥连接): 1.Jenkins主机生成SSH密钥 2.发送Jenkins主机公钥至要远程主机上 3.测试Jenkins主机免密连接远程主机

    2024年02月04日
    浏览(56)
  • Node.js:实现遍历文件夹下所有文件

    Node.js:实现遍历文件夹 代码如下 参考文章 如何使用Node.js遍历文件夹详解

    2024年02月13日
    浏览(52)
  • k8s集群Node节点管理:节点信息查看及节点label标签管理

    如果是kubeasz安装,所有节点(包括master与node)都已经可以对集群进行管理 如果是kubeadm安装,在node节点上管理时会报如下错误 只要把master上的管理文件 /etc/kubernetes/admin.conf 拷贝到node节点的 $HOME/.kube/config 就可以让node节点也可以实现kubectl命令管理 1, 在node节点的用户家目录创建

    2024年02月03日
    浏览(51)
  • Elasticsearch:节点角色 - node roles

    你可能已经知道 Elasticsearch 集群由一个或多个节点组成。 每个节点将数据存储在分片上,每个分片存储在一个节点上。 到目前为止,你看到的每个节点都至少存储了一个分片,但值得注意的是,节点并不总是必须存储分片。 这是因为每个节点可能具有一个或多个角色,这些

    2024年02月16日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包