三态树编程
- 格式:doc
- 大小:125.50 KB
- 文档页数:17
Scratch分形树作者:来源:《电脑报》2021年第41期在計算机科学中数据结构是计算机存储、组织数据的基础方式。
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
不同的数据结构可以通过不同的数学建模来搭建起来,今天就和大家分享一个最基础也是重要的数据结构图形:分形树。
什么是分形树呢?现实生活中植物的生长离不开生根、发芽、开花、结果,大树也同样如此,大树由下到上主要分为四个部分:粗壮的树根,树根的上面则是分出来的树干,树干上又生长出很多小的树枝,树枝上才有了树叶、花朵、果实等等。
依照大树的生长模型我们可以设计出分形树的模样。
分形树从树干开始一直分叉,依照2的N次方公式进行分叉,每次分叉的过程中树枝的长度都会有规律地减少,一直分叉到树的末梢;所形成的分形树为左右对称的图形,添加上对应的颜色后宛如一棵真正的参天大树。
了解了分形树的介绍和图形后,不知道你有没有想到通过Scratch画笔绘制出分形树的思路呢?看到这里大家可以先暂停一下想一想你自己的思路与方法。
下面请跟随小陈老师分析的过程:其实分形树的本质就是利用递归函数,首先确定初始的位置然后向上绘制树干,树干绘制完后,需要进行左右的分叉绘制树枝,当然在绘制过程中画笔不可能左右同时进行绘制,必须先绘制完一侧的树枝后,退回分叉点,回到原方向,再朝着另一侧绘制。
这里为了方便理解,我用Scratch画笔绘制出一个简单的分形树Y供大家参考,在舞台区域用数字编号表示了绘制的过程,如果我们想绘制多个分支结构的时候,就需要使用递归的思想了。
递归,指一种通过重复将问题分解为同类的子问题而解决问题的方法。
在分形树中,我们需要新建一个自制积木来控制绘制树丫分叉过程和绘制树枝的长度。
默认情况下我们将起始的树枝长度设置为50,因为在旋转移动的过程中,树枝的长度是随着分叉的过程不断地减少。
因此在自定义积木中便可以添加递归的过程,为了防止分形树一直重复无止尽递归,需要添加控制的条件,当树枝的长度小于10的时候停止递归,若满足条件则将树枝的长度减少10后绘制新的分叉。
#### 实验名称:多态编程应用#### 实验日期:2023年11月15日#### 实验环境:Java Development Kit (JDK) 1.8,Eclipse IDE#### 实验目的:1. 理解多态的概念及其在面向对象编程中的重要性。
2. 通过具体实例学习多态的应用,包括方法重写和向上转型。
3. 掌握多态在处理不同类型对象时的灵活性和效率。
#### 实验内容:一、实验背景多态是面向对象编程的三大基本特性之一,它允许不同类的对象对同一消息做出响应。
在Java中,多态主要通过方法重写和向上转型来实现。
本实验旨在通过设计一个简单的动物管理系统,来演示多态在实际编程中的应用。
二、实验设计1. 定义一个抽象类`Animal`,其中包含一个抽象方法`makeSound`。
2. 创建几个继承自`Animal`的具体类,如`Dog`、`Cat`和`Bird`,并分别实现`makeSound`方法。
3. 设计一个`AnimalManager`类,用于管理不同类型的动物对象。
4. 在`AnimalManager`类中,使用多态特性展示不同动物的叫声。
三、实验步骤1. 创建抽象类`Animal`:```javapublic abstract class Animal {public abstract void makeSound();}```2. 创建具体类`Dog`、`Cat`和`Bird`:```javapublic class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("Woof! Woof!"); }}public class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("Meow! Meow!"); }}public class Bird extends Animal {@Overridepublic void makeSound() {System.out.println("Tweet! Tweet!"); }}```3. 创建`AnimalManager`类:```javapublic class AnimalManager {public void manageAnimals(Animal[] animals) {for (Animal animal : animals) {animal.makeSound();}}}```4. 编写主类`Main`,用于测试多态应用:```javapublic class Main {public static void main(String[] args) {Animal[] animals = new Animal[3];animals[0] = new Dog();animals[1] = new Cat();animals[2] = new Bird();AnimalManager manager = new AnimalManager(); manager.manageAnimals(animals);}}```四、实验结果与分析运行`Main`类,输出结果如下:```Woof! Woof!Meow! Meow!Tweet! Tweet!```实验结果显示,通过多态,`AnimalManager`类能够处理不同类型的动物对象,并调用它们各自特有的`makeSound`方法。
数控编程语言的抽象语法树与代码生成方法数控编程语言是一种用于控制数控机床进行加工的语言。
在数控编程中,抽象语法树(Abstract Syntax Tree,AST)是一种重要的数据结构,用于表示源代码的抽象语法结构。
代码生成方法则是将抽象语法树转化为可执行的机器指令的过程。
本文将介绍数控编程语言的抽象语法树和代码生成方法。
一、抽象语法树(AST)抽象语法树是一种树状结构,用于表示源代码的语法结构。
在数控编程中,抽象语法树由多个节点组成,每个节点代表一个语法结构,如语句、表达式、变量等。
节点之间通过父子关系连接,形成一个层次结构。
抽象语法树的构建一般分为词法分析和语法分析两个阶段。
词法分析将源代码分解为词法单元(tokens),如关键字、标识符、运算符等。
语法分析则根据词法单元构建抽象语法树。
在语法分析过程中,会根据语法规则进行语法检查,并生成相应的节点。
抽象语法树的节点类型根据编程语言的语法规则而定。
在数控编程中,常见的节点类型包括程序节点、语句节点、表达式节点等。
每个节点都包含了与之相关的信息,如节点类型、节点值、子节点等。
二、代码生成方法代码生成是将抽象语法树转化为可执行的机器指令的过程。
在数控编程中,代码生成的目标是生成数控机床能够执行的控制指令。
代码生成方法一般包括以下几个步骤:1. 遍历抽象语法树:首先,需要遍历抽象语法树的节点,按照一定的顺序进行处理。
遍历的方式可以是深度优先遍历或广度优先遍历,具体取决于编程语言的特点和需求。
2. 生成中间代码:在遍历的过程中,可以根据节点的类型和值生成相应的中间代码。
中间代码是一种与具体机器无关的代码表示形式,可以方便后续的优化和转换。
3. 优化中间代码:生成的中间代码可能存在冗余或低效的部分,需要进行优化。
常见的优化方法包括常量折叠、公共子表达式提取、循环优化等。
4. 生成目标代码:最后,将优化后的中间代码转化为目标代码,即数控机床能够执行的控制指令。
单片机设计及应用知到章节测试答案智慧树2023年最新上海电力大学绪论单元测试1.本课程的学习目标为()。
参考答案:包括单片机的基本工作原理、单片机的硬件接口技术、汇编语言软件程序设计2.本课程的考试及格率为()。
参考答案:50~75%3.本课程的选修课程为()。
参考答案:计算机基础;电子电路;C语言第一章测试1.微型计算机采用总线结构()。
参考答案:可以简化系统结构、易于系统扩展2.微机的地址总线功能是()。
参考答案:用于传送要访问的存储器单元或I/O端口的地址3.在微机中将各个主要组成部件连接起来,组成一个可扩充基本系统的总线称之为( )。
参考答案:系统总线4.微型计算机的存储系统一般指主存储器和()。
参考答案:辅助存储器5.计算机的工作原理是存储程序控制,所以计算机中的程序都是顺序执行的。
()参考答案:错6.在计算机中,程序和数据都是以二进制形式不加区别存放的。
()参考答案:对7.已知[X]原=11101001,则[X]反=00010110。
()参考答案:错8.800H =2KB。
()参考答案:对9.8位二进制数补码的大小范围是-127∽+127。
()参考答案:错10.-128的补码是10000000。
()参考答案:对11.将十进制(0.825)10转换成二进制数是(0.1101)2。
()参考答案:错12.计算机中负数的反码是把它对应的正数连同符号位按位取反而开形成的。
()参考答案:错13.单片机在调试过程中,通过查表将源程序转换成目标程序的过程叫()。
参考答案:手工汇编14.将十进制数98转换成对应的二进制数是()。
参考答案:110001015.二进制数110110110对应的十六进制数可表示为()。
参考答案:1B6H16.已知[X]补=00000000,则真值X=()。
参考答案:17.计算机中最常用的字符信息编码是()。
参考答案:ASCII18.处理器的内部数据宽度与外部数据宽度可以()参考答案:相同或不同19.中央处理器是由()构成的。
vhdl课程设计三态门一、教学目标通过本节课的学习,学生应掌握三态门的基本原理和VHDL语言的编程方法,能够独立完成三态门电路的设计和验证。
具体目标如下:1.了解三态门的基本原理和功能;2.掌握VHDL语言的基本语法和编程方法;3.熟悉三态门电路的设计流程和验证方法。
4.能够运用VHDL语言编写三态门电路的代码;5.能够使用相关工具对三态门电路进行仿真和验证;6.能够分析并解决三态门电路设计中遇到的问题。
情感态度价值观目标:1.培养学生的创新意识和团队协作精神;2.增强学生对电子工程领域的兴趣和热情;3.培养学生严谨的科学态度和良好的沟通能力。
二、教学内容本节课的教学内容主要包括以下几个部分:1.三态门的基本原理和功能;2.VHDL语言的基本语法和编程方法;3.三态门电路的设计流程和验证方法;4.实际案例分析和相关练习。
具体的教学大纲如下:1.引言:介绍三态门的概念和应用场景;2.三态门的基本原理:讲解三态门的工作原理和电路结构;3.VHDL语言基础:介绍VHDL语言的基本语法和编程方法;4.三态门电路设计:讲解三态门电路的设计流程和注意事项;5.电路验证与仿真:介绍如何使用相关工具对三态门电路进行仿真和验证;6.案例分析与练习:分析实际案例,并进行相关练习。
三、教学方法为了提高学生的学习兴趣和主动性,本节课将采用以下教学方法:1.讲授法:讲解三态门的基本原理和VHDL语言的基本语法;2.讨论法:引导学生进行小组讨论,共同解决问题;3.案例分析法:分析实际案例,让学生更好地理解三态门电路的设计和验证;4.实验法:引导学生动手实践,完成三态门电路的设计和验证。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将准备以下教学资源:1.教材:提供相关教材,为学生提供理论知识的学习参考;2.参考书:提供相关参考书,帮助学生深入了解三态门电路的设计和验证;3.多媒体资料:制作课件和教学视频,为学生提供直观的学习资源;4.实验设备:准备实验设备,让学生能够动手实践,提高实际操作能力。
DHTMLX Tree中文开发指导(转载)浮石收录于2010-03-10 阅读数:公众公开原文来源最近开发项目使用到了dhtmlXtree做权限设置,看了网上相关的中文资料很少,就把官方的资料翻译了下,一共分2部分,API可以参考官方文档:/docs/download.shtml效果图如下(三态树):dhtmlXTree 指南与实例主要特性多浏览器/多平台支持全部由JavaScript控制动态加载XML支持大数据树动态翻译(智能XML解析)拖拽(同一个树,不同的树之间,不同的框架之间)带多选框(CheckBox)的树(两态/三态)定制图标(使用JavaScript或xml)内容菜单(与dhtmlxMenu集成)结点数据为用户数据多行结点高稳定性支持Macromedia Cold Fusion支持Jsp支持支持以下浏览器IE 5.5或更高版本Mac OS X SafariMozilla 1.4 或更高版本FireFox 0.9 或更高版本Opera (Xml加载支持取决于浏览器版本)使用dhtmlXTree进行开发在页面初始化对象<div id="treeBox" );tree.enableCheckBoxes(false);tree.enableDragAndDrop(true);</script>构造器有以下参数:加载树的容器对象(应该在调用构造器之前被加载)树的宽度树的高度树根的父结点的id(超级根)指定树的其他参数:setImagePath(url) - 设置树所使用的图片目录地址enableCheckBoxes(mode) - 打开/关闭多选框(默认打开)enableDragAndDrop(mode) - 打开/关闭拖拽模式设置事件处理1.5以上的版本支持一种新的设置事件的方式-使用attachEvent方法.设置一个事件处理方法需要知道事件的名字和所调用的方法.可用的事件名参考这里(以后会翻译),在事件处理方法中,可以这样引用树对象:<div id="treeBox" ,onNodeSelect)//set function object to call on node select //see other available event handlers in API documentationfunction onNodeSelect(nodeId){...}</script>很多时候函数要从参数中获取值.关于传值得详细信息请参考事件文档(以后翻译)使用脚本增加结点<script>tree=new dhtmlXTreeObject('treeBox',"100%","100%",0);...tree.insertNewChild(0,1,"New Node1",0,0,0,0,"SELECT,CALL,TOP,CHILD,CHECKED");tree.insertNewNext(1,2,"New Node 2",0,0,0,0,"CHILD,CHECKED");</script>第4-7的参数都是0(选择后调用的方法,所使用的图片)意味着都使用默认值最后一个使用逗号分隔的参数可以是以下值(只能是大写):SELECT - 插入后选择此结点CALL - 在选择时调用方法TOP - 在最上方插入此结点CHILD - 此结点有子结点CHECKED - 此结点的多选框被选中(如果有的话)使用XML加载数据<script>tree=new dhtmlXTreeObject('treeBox',"100%","100%",0);tree.setXMLAutoLoading("http://127.0.0.1/xml/tree.xml");tree.loadXML("http://127.0.0.1/xml/tree.xml");//load root level from xml</script>在调用时,被打开的结点id(就像url参数一样)将会被增加到初始化XMLAutoLoading(url) 的URL地址上去调用loadXML(url)方法不会增加id到url地址上调用无参的loadXML()将会使用XMLAutoLoading(url)所指定的url地址XML语法:<?xml version='1.0' encoding='iso-8859-1'?><tree id="0"><item text="My Computer" id="1" child="1" im0="my_cmp.gif" im1="my_cmp.gif" im2="my_cmp.gif" call="true" select="yes"><userdata >PHP脚本需要在页面头添加以下代码:<?phpif ( stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml") ) { header("Content-type: application/xhtml+xml"); } else {header("Content-type: text/xml");}echo("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");?><tree>结点是必须有的.指定加载数据的父结点.这个id参数指定了父结点id.加载根层需要在创建树的时候指定id:new myObjTree(boxObject,width,height,0)<itrem>可以包含(为了一次加载多层结点)或者不包含子结点.并且可以包含<itemtext>标签,可以为结点标签(label)增加一些HTML (text属性将会被忽略)<item id="123"><itemtext><![CDATA[<font color="red">Label</font>]]></itemtext></item>必要属性有:text - 结点显示的标签id - 结点id可选属性有:tooltip -鼠标放在结点上提示的信息im0 - 没有子结点的结点显示的图片(将会从setImagePath(url)方法指定的路径去获取图片)im1 - 包含子结点的结点展开时显示的图片im2 - 包含子结点的结点关闭时显示的图片aCo1 - 没有选中的结点的颜色sCol - 选中的结点的颜色select -在加载时选择此结点(可以为任意值)style - 结点文本风格open - 展开此结点(可以为任意值)call - 选择时调用函数(可以为任意值)checked - 如果存在的话,选择此结点的多选框(可以为任意值)child - 指定结点是否有子结点(1:有,0:无)imheight - 图标的高度imwidth - 图标的宽度topoffset - 设置结点和上层结点间的偏移量radio - 如果非空则此结点的子结点会有单选按钮直接在XML里面设置用户数据可以使用<userdata>标签,此标签只有一个参数:name和 value 去指定用户数据值为结点定制图标有两种方法去定制结点图标,这取决于增加结点的方式.注意:树将会从setImagePath(url)方法指定的路径去获取结点图片.Javascript的方式:使用insertNewChild(...)或者insertNewNext(...)方法的参数指定<script>var im0 = "doc.gif";//icon to show if node contains no childrenvar im1 = "opened.gif";//if node contains children and openedvar im2 = "closed.gif";//if node contains children and closedtree.insertNewItem(0,1,"New Node 1",0,im0,im1,im2);tree.insertNewNext(1,2,"New Node 2",0,"txt.gif","opened.gif","closed.gif"); </script>XML的方式.使用<item>标签的属性:<?xml version='1.0' encoding='iso-8859-1'?><tree id="0"><item text="My Computer" id="1" child="1" im0="doc.gif" im1="my_opened.gif" im2="my_closed.gif"></tree>im0 - 没有子结点的结点显示的图片(将会从setImagePath(url)方法指定的路径去获取图片)im1 - 包含子结点的结点展开时显示的图片im2 - 包含子结点的结点关闭时显示的图片构建动态树如果树包含很大数量的结点(或者你只是不想浪费时间去加载隐藏的结点),按照需要去加载他们似乎是更好的选择,而不是一次性的全部加载进来.因此我们使用XML动态加载树.请参考"使用XML加载数据"或者查阅"Dynamical Loading in dhtmlxTree v.1.x"操作结点一些使用树的方法来操作结点的例子:<script>tree=new dhtmlXTreeObject('treeboxbox_tree',"100%","100%",0);...var sID = tree.getSelectedItemId();//get id of selected nodetree.setLabel(sID,"New Label");//change label of selecte nodetree.setItemColor(sID,'blue','red');//set colors for selected node's label (for not selected state and for selected state)tree.openItem(sID);//expand selected nodetree.closeItem(sID);//close selected nodetree.changeItemId(sID,100);//change id of selected node to 100alert("This node has children: "+tree.hasChildren(100));//show alert with information if this node has children</script>序列化树序列化方法允许从xml表现形式(xml字符串)中获取树.不同程度的序列化会在生成的XML 字符串的属性上面反映出来<script>tree.setSerializationLevel(userDataFl,itemDetailsFl);var myXmlStr = tree.serializeTree();</script>没有参数的序列化- id,open,select,text,child参数userDataFl true - userdata参数itemDetailsFl true - im0,im1,im2,acolor,scolor,checked,openTooltips (鼠标放在结点上所提示的内容)有三种方法去设置tooltip :使用结点的label("text"item结点的text属性)作为tooltip -enableAutoTooltips(mode) - 默认为false使用item结点的"tooltip"属性作为tooltip(如果此属性被设置了则默认使用此方法)使用setItemText(itemId,newLabel,newTooltip) 方法移动结点编程式的移动可以使用以下方法:向上/下/左移动:tree.moveItem(nodeId,mode)mode 可以是以下值:"down" -把结点移动到下方(不用再意层次关系)"up" - 把结点移动到上方"left" - 把结点直接移动到上层位置直接移动到指定位置(在树内部)tree.moveItem(nodeId,mode,targetId)mode 可以是以下值:"item_child" - 把结点移动到第三个参数子结点的位置作为子结点"item_sibling" -把结点移动到第三个参数兄弟结点的位置作为兄弟结点targetId - 目标结点的Id To move node into position (to another tree)移动结点到指定位置(另一个树)tree.moveItem(nodeId,mode,targetId,targetTree)mode 的值参考以上两个例子 targetId - 目标结点的Id(在targetTree里面的id). targetTree - 目标树对象剪切/粘贴的方式另一种方式是使用doCut()和doPaste(id)函数-但是这种方法只能对选中的结点有效.程序员也可以从一个位置删除一个结点然后再另外一个地方再创建一个(也是个办法:-)).提供给用户拖拽功能去移动结点结点计数器可以显示指定结点标签(label)的结点子元素的数量.激活此方法使用以下代码:<script>tree.setChildCalcMode(mode);</script>mode 可以是以下值:"child" - 这层的所有子结点"leafs" - 这层的所有没有子结点的子结点"childrec" - 所有子结点"leafsrec" -没有子结点的所有子结点"disabled" - 什么都没有其他相关方法: _getChildCounterValue(itemId) - 得到当前的记数值setChildCalcHTML(before,after) - 包含计数器的html代码如果在动态加载中需要设定计数器的值,请在xml中使用child属性智能XML解析智能XML解析的概念很简单-整个树结构是从客户端加载的,但是只有应该被显示的结点才会被展示出来.很有效的减少了加载时间和大数据量树的性能.另外-与动态加载相反的是-脚本方法可以使用整个树结构(比如搜索整个树-而不是只有被显示出来的)用以下方法激活智能XML解析:<script>tree.enableSmartXMLParsing(true);//false to disable</script>在树被完全展开的时候只能XML解析不会产生作用树的多选框dhtmlxTree支持两态和三态树.三态树有三种状态:选中/未选中/某些子结点被选中(不是全部)用以下方法激活三态树:<script>tree.enableThreeStateCheckboxes(true)//false to disable</script>使用智能XML解析的话需要手工设置第三种状态(checked="-1");<item checked="-1" ...><item checked="1" .../><item .../></item>Checkboxes可以被禁用-disableCheckbox(id,state)一些结点可以隐藏checkboxes - showItemCheckbox(id,state) (nocheckbox xml 属性) 版本1.4以后 showItemCheckbox可以对整棵树使用(第一个参数使用0或者null)树的单选框dhtmlxTree支持但选按钮使用以下代码对整棵树进行设置<script>tree.enableRadiobuttons(true);</script>对某些特定的结点使用单选按钮(代替多选框)<script>tree.enableCheckboxes(true);tree.enableRadiobuttons(nodeId,true);</script>默认情况下单选按钮是根据层次分组的,但是版本1.4以后可以对整棵树进行设置:tree.enableRadiobuttons(true)Checkboxs相关的API和XML属性也适用于radiobuttons(参考radiobuttons方法描述)拖拽技术拖拽有三种模式(使用setDragBehavior(mode)方法进行设置)当作子结点拖拽-"child"当作兄弟结点拖拽-"sibling"复合模式(前两种模式一起)- "complex" 每一种模式还有两种子模式:1. 普通拖拽2. 复制拖拽 - tree.enableMercyDrag(1/0)所有模式都可以在运行时改变事件处理在处理结点放下之前的事件使用-attachEvent("onDrag",func)如果func没有返回true,将会取消拖拽.将结点放下后会有另一个事件-onDrop-使用attachEvent("OnDrop",func)进行处理.两种方法都会传给func对象5个参数被拖拽结点的id目标结点的id前目标结点(如果拖拽的是兄弟结点)源树对象目标树对象两个框架之间的拖拽默认情况下框架间的拖拽是开启的.只需要把下列代码加在页面上没有树的地方<script src="codebase/dhtmlxcommon.js"></script><script>new dhtmlDragAndDropObject();</script>提高性能如果生成DHTML树的性能很低,有两种途径去改进大数据树的性能:1.Dynamical Loading(动态加载)2.Smart XML Parsing(智能XML解析)3.Distributed Parsing(分布式解析)4.Smart Rendering(动态显示)另外确保你的树组织的很好-把很多个结点放在同一层很不美观并且降低性能,虽然分布式解析或者智能显示可以解决这个问题上下文菜单在dhtmlxTree里面可以构建上下文菜单.菜单的上下文可以使用XML或者脚本进行设置.改变上下文菜单内容取决于树结点开发人员可以实现函数隐藏/显示同一个菜单的结点或者不同菜单的不同结点.下面的代码激活上下文菜单<script>//init menuaMenu=new dhtmlXContextMenuObject('120',0,"../codebase/imgs/");aMenu.menu.loadXML("menu/_context.xml");aMenu.setContextMenuHandler(onMenuClick);//init treetree=new dhtmlXTreeObject("treeboxbox_tree","100%","100%",0);...tree.enableContextMenu(aMenu); //link context menu to treefunction onMenuClick(id){alert("Menu item "+id+" was clicked");}HTTPS 兼容为了兼容HTTPS,我们需要为上下文菜构造器增加两个参数Images URLDummy page URL (url of the page to use for iframes src /now they are empty as iframes are used to make menu be positioned under selectboxes in IE/ in menu to make it compatible with https)<script>//init menu compatible with sHTMLaMenu=new dhtmlXContextMenuObject('120',0,"imgs/","empty.html");...</script>刷新结点refreshItems(itemIdList,source) 仅刷新itemIdList里面的结点(不包含它们的子结点) refreshItem(itemId) - 刷新itemId指定的子结点.自动加载会被激活结点排序专业版本中可以对结点进行排序(需要dhtmlxtree_sb.js)使用以下方式:根据标签(label)文本(如果没有定制比较描述符)tree.sortTree(nodeId,order,all_levels);nodeId -开始排序层的父结点id(如果是超级根Id,排序整棵树)order - 排序方向:"升序"/"降序"all_levels - 如果为true,则所有子层都会被排序//define your comparator (in our case it compares second words in label)function mySortFunc(idA,idB){a=(tree.getItemText(idA)).split(" ")[1]||"";b=(tree.getItemText(idB)).split(" ")[1]||"";return ((a>b)?1:-1);}tree = new ...//attach your comparator to the treetree.setCustomSortFunction(mySortFunc);比较函数有两个结点id,使用树对象和id返回一个比较结果.如果定制比较函数被指定.则tree.sortTree(...)方法使用此函数排序查找功能dhtmlxTree的查找功能允许开发人员把注意力从匹配标签(label)搜索码中解脱出来,支持智能XML解析脚本语法tree.findItem(searchString); //find item next to current selectiontree.findItem(searchString,1,1)//find item previous to current selectiontree.findItem(searchString,0,1)//search from top例子包含在专业版中-samples/treeExPro2.html多行结点允许在多行显示树结点.建议关掉避免影响外观.开启多行功能需要以下代码:tree.enableTreeLines(false);tree.enableMultiLineItems(true);例子包含在专业版中-samples/treeExPro6.html树的图标设置图标有一种方法可以使用脚本设置图标(setItemImage,setItemImage2)或者xml (im0,im1,im2 attributes of item node):im0 - 没有子结点的结点im1 - 有子结点的关闭结点im2 - 有子结点的打开结点设置图标大小有一种方法可以使用脚本或者xml为整棵树或者每个结点设置图标大小: XML设置每个结点的图标大小(可选):<item ... imheight="Xpx" imwidth="Xpx"></item>脚本语法:tree.setIconSize(w,h);//set global icon sizetree.setIconSize(w,h,itemId)//set icon size for particular item键盘导航默认情况下dhtmlxTree没有支持键盘功能,但是可以在页面中增加dhtmlxtree_kn.js 文件去开启键盘支持,只需要下面一条指令:<script src="../codebase/ext/dhtmlxtree_kn.js"></script><script>tree.enableKeyboardNavigation(true);</script>默认按键:Up arrow - 选择上面的结点Down arrow - 选择下面的结点Right arrow - 打开结点Left arrow - 关闭结点Enter - 调用结点方法也可以指定自己的按键如下:tree.assignKeys([["up",104],["down",98],["open",102],["close",100],["call",101] ]);"up"/"down"/"open"/"close"/"call" 是可用的动作,数字是按键代码分布式解析另一种增加大数据树(每层100-200个结点)性能的方法是分布式解析,这个是企业版才有的功能.最大的好处是可以在树完全被解析之前看到树的层次并准备使用.使用以下命令激活这个功能:<script>tree.enableDistributedParsing(mode,count,timeout);</script>参数:mode - 必要参数- true/false - 开启/关闭分布解析count - 可选参数- 分配结点的数量timeout - 可选参数- 两部分结点之间延迟的毫秒数,这个功能完全和智能XML解析兼容错误处理一些dhtmlxTree异常可以被捕获并且处理function myErrorHandler(type, desc, erData){alert(erData[0].status)}dhtmlxError.catchError("ALL",myErrorHandler);支持错误类型:"All""LoadXML"处理函数参数:type - 字符串(如上)desc - 错误描述(硬编码)erData - 错误相关对象数组(如下).Type Object(s)LoadXML [0] - response objectCold Fusion 标签<cf_dhtmlXTree>...configuration xml...</cf_dhtmlXTree>name - [optional] name of the tree js object to use in javascript, if skiped, then name autogeneratedwidth - [optional] width of the tree (definitely it sets the with of the tree box, leaving the with of the tree itself by 100%)height - [optional] height of the treeJSPath - [optional] absolute or relative path to directory which contains tree js files, "js" directory by defaultCSSPath - [optional] absolute or relative path to directory which contains tree css files, "css" directory by defaulticonspath - [optional] absolute or relative path to directory which contains tree icon files, "img" directory by defaultxmldoc - [mandatory for xml loading] url of the xml file used to load levels dynamicallycheckboxes - [optional] show checkboxes (none, twoState, threeState) dragndrop - [optional] activate drag-&-drop (true,false)style - [optional] style for the tree boxonSelect - [optional] javascript function to call on node selectiononcheck - [optional] javascript function to call on node (un)checkingonDrop - [optional] javascript function to call on node dropim1 - [optional] default image used for child nodesim2 - [optional] default image used for opened branchesim3 - [optional] default image used for closed branches For description of optional configuration xml - see chapter "Loading data with XML"Minimal possible tag syntax with on-page xml:<cf_dhtmlXTree><item text="Top node" id="t1" ><item text="Child node 1" id="c1" ></item><item text="Child node 2" id="c2" ></item></item></cf_dhtmlXTree>Minimal possible tag syntax with server-side xml:<cf_dhtmlXTree xmldoc="tree.xml"></cf_dhtmlXTree>With images specified:<cf_dhtmlXTreeim1="book.gif"im2="books_open.gif"im3="books_close.gif"><item text="Mystery " id="mystery" open="yes" ><item text="Lawrence Block" id="lb" ><item text="All the Flowers Are Dying" id="lb_1" /><item text="The Burglar on the Prowl" id="lb_2" /><item text="The Plot Thickens" id="lb_3" /><item text="Grifters Game" id="lb_4" /><item text="The Burglar Who Thought He Was Bogart" id="lb_5" /> </item><item text="Robert Crais" id="rc" ><item text="The Forgotten Man" id="rc_1" /><item text="Stalking the Angel" id="rc_2" /><item text="Free Fall" id="rc_3" /><item text="Sunset Express" id="rc_4" /><item text="Hostage" id="rc_5" /></item><item text="Ian Rankin" id="ir" ></item><item text="James Patterson" id="jp" ></item><item text="Nancy Atherton" id="na" ></item></item></cf_dhtmlXTree>With Events Handlers,Checkboxes and Drag-n-drop:<cf_dhtmlXTreedragndrop="true"checkboxes="twoState"onSelect="onClick"onCheck="onCheck"onDrop="onDrag"><item text="Mystery " id="mystery" open="yes" ><item text="Lawrence Block" id="lb" ><item text="All the Flowers Are Dying" id="lb_1" /><item text="The Burglar on the Prowl" id="lb_2" /><item text="The Plot Thickens" id="lb_3" /><item text="Grifters Game" id="lb_4" /><item text="The Burglar Who Thought He Was Bogart" id="lb_5" /> </item><item text="Robert Crais" id="rc" ><item text="The Forgotten Man" id="rc_1" /><item text="Stalking the Angel" id="rc_2" /><item text="Free Fall" id="rc_3" /><item text="Sunset Express" id="rc_4" /><item text="Hostage" id="rc_5" /></item><item text="Ian Rankin" id="ir" ></item><item text="James Patterson" id="jp" ></item><item text="Nancy Atherton" id="na" ></item></item></cf_dhtmlXTree>可编辑结点1.3版本后dhtmlxTree专业版可以使用可编辑结点.只须在页面中引用dhtmlxtree_ed.js去开启这个功能:<script src="../codebase/ext/dhtmlxtree_ed.js"></script><script>tree.enableItemEditor(mode);</script>参数如下:mode - 必要参数- true/false - 开启/关闭可编辑结点Event: 使用事件处理可以处理可编辑结点的不同阶段的事件,可以使用attachEvent("onEdit",handlerFunc)来设置. 在编辑过程中有4个不同的阶段:开始编辑前(可取消),编辑开始后,编辑结束前(可取消),编辑结束后处理方法的4个参数如下: state - 0 开始编辑前, 1 编辑开始后, 2 编辑结束前, 3 编辑结束后id - 可编辑结点的idtree - 树对象value -只有2阶段可以使用,编辑的值同步与服务器更新通常的树操作-比如拖拽(包括不同树间的),删除结点,插入结点,更新结点标签(label)-在1.3版本后可以使用数据处理模型(dataProcessor module)与服务器上的数据库进行同步更新.主要特性如下:更新/插入结点,使用黑体字,删除结点-使用一条横线穿过可以定义数据处理模式(自动/手动).更新/删除结点的数据发送到指定的服务器URL(我们叫它服务器处理器).服务器处理器应该可以返回普通的xml和自定的格式化格式(如下),让树知道服务器是否成功进行处理,所有存储后的过程都会被自动处理使用以下步骤开启此功能:页面中包含dhtmlxdataprocessor.js为树创建数据处理(dataProcessor)对象<script src="../codebase/dhtmlxdataprocessor.js"></script><script>...tree.init();myDataProcessor = new dataProcessor(serverProcessorURL);myDataProcessor.init(treeObj);</script>dataProcessor构造器参数如下:serverProcessorURL - 必要参数- 处理接收数据文件的Url地址.如果使用服务器端运行.那么就是"dhtmlxDataProcessor/server_code/PHP/update.php?ctrl=tree" myDataProcessor.init方法的参数是:treeObj - 必要参数- 分配数据处理器(dataProcessor )的树对象如果不需要使用built-in服务器处理器(serverProcessor)而是使用自己的文件处理数据,需要知道以下几点:所有数据从Get域中获取- tr_id - 结点ID - tr_order - 同层结点顺序 - tr_pid - 父结点 - tr_text -结点文字(label) - 用户数据块和名字一起传来 - !nativeeditor_status - 如果存在并且值是"inserted"则为插入操作,值为"deleted"为删除操作,不存在或者值为"updated"是更新操作服务器处理器(serverProcessor )应该返回以下格式的XML数据:<data><action type='insert/delete/update' sid='incomming_node_ID'tid='outgoing_node_ID'/></data>只有对于插入结点来说incomming_node_ID和outgoing_node_ID 是两个不同的值.其他操作这两个值时一样的.对于统一服务器端运行时(PHP5/mySQLk可用)使用以下步骤: yourTree.loadXML(url) 使用"dhtmlxDataProcessor/server_code/PHP/get.php?ctrl=tree" 为参数new dataProcessor(url) 使用"dhtmlxDataProcessor/server_code/PHP/update.php?ctrl=tree" 为参数在dhtmlxDataProcessor/server_code/PHP/db.php 中配置连接在dhtmlxDataProcessor/server_code/PHP/tree_data.xml 中指定表的相应列值从HTML初始化可以使用html List或者内联XML来创建一个树.无论哪种方法都要在放置在一个DIV元素里面,DIV元素当作树的容器(XML应该包含XMP标签-见下面代码)任何树以set或者enable 开头的方法可以当作DIV元素的属性使用去设置树的属性.可以自动转换或者调用脚本函数自动转换在页面中包含 dhtmlxtree_start.js把DIV元素的class属性设置为dhtmlxTree使用脚本方法转换在页面中包含 dhtmlxtree_start.js调用dhtmlXTreeFromHTML函数,把DIV元素的id当作第一个参数传进去var myTree = dhtmlXTreeFromHTML('listBox');使用html List初始化<divclass="dhtmlxTree"id="treeboxbox_tree"setImagePath="../codebase/imgs/"><ul><li>Root</li><ul><li>Child1<ul><li>Child 1-1</li></ul></li><li>Child2</li><li>Bold Italic </li></ul></li></ul></div>使用内联XML初始化关于dhtmlxTree XML结构的详细内容清参照 Loading data with XML <div id="treeboxbox_tree2" setImagePath="../codebase/imgs/" class="dhtmlxTree" ><xmp><item text="Root" open="1" id="11"><item text="Child1" select="1" open="1" id="12"> <item text="Child1-1" id="13"/></item><item text="Child2" id="14"/><item id="15" text="Text"/></item>< /xmp></div>Version/Edition: v1.4/Professional/Standard Required js file:dhtmlxtree_start.js动态显示(Smart Rendering)如果树的每层都有很大数量的结点(500或者更多),可以尝试使用动态(Smart Rendering)显示来增加性能.数据结构不需要做任何变化-只需要使用enableSmartRendering打开此功能.注意:此方法和分布解析和三态树不兼容. Version/Edition: v1.5/Professional Required js file:dhtmlxtree_srnd.js从JSON加载从JSON加载树需要有JSON对象或者文件,并且使用以下方法加载:tree.loadJSONObject(JSON_OBJECT);//for loading from script objecttree.loadJSON(FILE);//for loading from file两个方法都有第二个可选参数-当数据被加载后执行的方法.JSON格式:结构类似树的XML结构,标签被翻译成对象,属性被翻译成字段{id:0,item:[{id:1,text:"first"},{id:2, text:"middle",item:[{id:"21", text:"child"}]},{id:3,text:"last"}]Version/Edition: v1.6/Professional/Standard Required js file:dhtmlXGrid_json.js从CSV加载数据需要使用CSV格式的字符串或者文件,使用以下方法加载:tree.loadCSV(FILE);//for loading from filetree.loadCSVString(CSVSTRING);//for loading from string两个方法都有第二个可选参数-当数据被加载后执行的方法.CSV格式:树结点被三个值所表示-id,parent_id,text.比如:1,0,node 12,1,node 1.13,2,node 1.1.14,0,node 2Version/Edition: v1.6/Professional/Standard Required js file:dhtmlXGrid_json.js 从JS数组加载执行以下方法从javascript对象或者javascript文件加载:tree.loadJSArrayFile(FILE);//for loading from filetree.loadJSArray(ARRAY);//for loading from array object两个方法都有第二个可选参数-当数据被加载后执行的方法.ARRAY格式:树结点被三个值所组成的子数组所表示-id,parent_id,text.比如:var treeArray = new Array(["1","0","node 1"],["2","1","node 1.1"],["3","2","node 1.1.1"],["4","0","node 2"])Version/Edition: v1.6/Professional/Standard Required js file:dhtmlXGrid_json.js精品文档。
在C语言中,算术表达式通常被解析并转换为抽象语法树(Abstract SyntaxTree,AST)。
这种树形结构表示了表达式中的运算符和操作数之间的关系。
以下是一个简单的例子,说明如何将一个算术表达式(例如"1 + 2 * 3")转换为一个抽象语法树。
1.解析表达式:首先,我们需要一个解析器来将字符串形式的算术表达式分解为单个的运算符和操作数。
例如,"1 + 2 * 3" 可以被解析为"1", "+", "2", "*", "3"。
2.构建抽象语法树:然后,我们可以使用这些分解后的元素来构建抽象语法树。
在我们的例子中,树的形状可能如下所示:markdown复制代码+|-- 1|-- *|-- 2|-- 3每个节点都代表一个运算符或操作数,子节点表示操作数,父节点表示运算符。
注意这个树的深度和表达式中的括号数量、运算符优先级和类型等因素有关。
C语言标准库并不包含构建这种抽象语法树的功能。
然而,有许多库和工具可以帮助你做这件事,比如Flex 和Bison(也称为"GNU Flex and Bison"),它们可以帮助你创建一个可以解析C语言表达式的工具。
你也可以自己编写解析器,但这通常需要深入理解编译器设计和编程语言理论。
如果你想在C语言中解析和计算算术表达式,一个简单的方法是使用字符串函数来手动解析表达式,然后使用函数来执行相应的数学运算。
但是这种方法对于复杂的表达式可能会变得非常复杂和容易出错。
使用现成的解析器和编译器工具可以帮助你避免这些问题。
绪论单元测试1.学习EDA技术这门课程的具体要求是()A:较好地掌握应用EDA技术进行系统设计开发的方法,具备应用EDA技术进行综合性数字系统设计的初步能力,经过后续的综合应用实践,能够从事FPGA的设计与开发、SOPC的设计与开发以及ASIC的前端设计等工作。
B:掌握EDA技术的基本概念、基础知识;了解FPGA/CPLD的结构、工作原理、性能指标及应用选择;熟练掌握硬件描述语言VHDL的编程;熟练掌握EDA技术的开发软件及EDA实验开发系统的使用。
C:初步掌握基于FPGA的VLSI系统设计与实现的方法和技术,具备分析、解决实际问题的能力,具有较强的专业实践能力和创新能力。
答案:ABC2.学习EDA技术这门课程,我们希望达到的学习目标是()A:基本掌握SOC的设计与开发方法B:掌握一种硬件描述语言VHDLC:基本掌握ASIC的后端设计与开发D:基本掌握SOPC的设计与开发方法E:熟悉FPGA的设计与开发F:基本掌握ASIC的前端设计与开发答案:BDEF3.EDA技术课程的学习要点是()A:运用四种手段(案例分析、应用设计、线上学习、上机实践)B:掌握两个工具(FPGA/CPLD开发软件、EDA实验开发系统的使用)C:抓住一个重点(硬件描述语言编程)D:以课题为中心,以研究式教学为主要形式E:采用五个结合(边学边用相结合、边用边学相结合、理论与实践相结合、线上与线下相结合、课内与课外相结合)答案:ABCDE第一章测试1.EDA的中文含义是()A:计算机辅助设计B:电子设计自动化C:计算机辅助工程设计答案:B2.狭义的EDA技术,就是指以大规模可编程逻辑器件为设计载体,以硬件描述语言为系统逻辑描述的主要表达方式,以计算机、大规模可编程逻辑器件的开发软件及实验开发系统为设计工具,通过有关的开发软件,自动完成用软件方式设计的电子系统到硬件系统的逻辑编译、逻辑化简、逻辑分割、逻辑综合及优化、逻辑布局布线、逻辑仿真,直至对于特定目标芯片的适配编译、逻辑映射、编程下载等工作,最终形成集成电子系统或专用集成芯片的一门新技术,或称为IES/ASIC自动设计技术。
示例代码运行效果图如下:在很多情况下,我们经常需要实现树的多态选择,如上图所示,当全部子节点选中的情况下,当前节点才被选中(如图示[荆门市]节点),当子节点部分选中时,当前节点处于第三态(如图示[湖北省]节点)当全部子节点未选中时,当前节点处于未选中的状态(如图示[江苏省]节点)。
本文就介绍这种三态选择树的具体实现方法。
在VC知识库第十九期中河南科技大学丛雷朋友也介绍了一种实现方法,两种方法比较,本文介绍的方法实现简单,兼容原CTreeCtrl的全部操作,CheckBox也是采用控件本身的CheckBox,只是在状态显示时重画而已。
因此,本方法可以实现表示三态的情况下同时显示节点ICON图标,另增加了对CheckBox在某些节点是否显示的控制,同时增加了对键盘空格键选中、取消选中的控制。
具体遍历父、子节点的方法同丛雷朋友朋友的方法类似,也是递归实现全部节点的遍历,只是优化了一些,效率更高。
下面介绍具体使用方法:步骤一:生成一个对话框工程(示例工程CMutiTree)。
步骤二:添加树控件,按照实际需要设置所需的属性。
步骤三:做节点图标和三态选择框图标一般情况下节点图标采用16×16,三态选择图标采用13×13大小比较合适。
三态选择图标对应: 0->无选择钮1->没有选择2->部分选择3->全部选择步骤四:将两个文件[MutiTreeCtrl.cpp ,MutiTreeCtrl.h]添加到步骤一创建的对话框工程中,在CMutiTreeDlg类的头文件中增加对[MutiTreeCtrl.h]的包含,此时工程中增加了CMutiTreeCtrl类。
#include "MutiTreeCtrl.h"步骤五:用ClassWizard在CmutiTreeDlg中创建一个树控件CTreeCtrl的对象m_TripleTree,更改该对象为上面步骤四加入的CMutiTreeCtrl类的对象。
步骤六:在CMutiTreeDlg类中定义两个CImageList 类的对象,用于加载CMutiTreeCtrl所需要的节点图标列表和三态选择框图标列表。
在CMutiTreeDlg类的头文件中:CImageList m_imgList;CImageList m_imgState;在对话框的初始化函数中:m_imgState.Create(IDB_BITMAP_STATE,13, 1, RGB(255,255,255));m_imgList.Create(IDB_BITMAP_LIST,16, 1, RGB(255,255,255));m_TripleTree.SetImageList(&m_imgList,TVSIL_NORMAL);m_TripleTree.SetImageList(&m_imgState,TVSIL_STATE);完成以上六步操作后,编译、运行,用键盘空格键或鼠标单击CheckBox改变其状态,您将看到不需要再增加任何代码,已经实现了三态选择树的功能。
如果需要隐藏某些选择框,如根节点的选择框,只需要设置对应的节点状态为0即可:m_TripleTree.SetItemState( hRoot, INDEXTOSTATEIMAGEMASK(0),TVIS_STATEIMAGEMASK );上述代码将设置根节点不显示三态选择框。
我具体实现的思想是以Windows标准的CTreeCtrl类为基类派生一个类CMutiTreeCtrl,截获键盘和鼠标点击CheckBox的事件,在此消息响应函数中,更改CheckBox的状态,并搜索子节点、兄弟节点和父节点,更改其状态与上述逻辑一致。
方法如下介绍:一、CTreeCtrl类为基类派生CMutiTreeCtrl类class CMutiTreeCtrl : public CTreeCtrl{// Constructionpublic:CMutiTreeCtrl();// Attributespublic:// Operationspublic:// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CMutiTreeCtrl)//}}AFX_VIRTUAL// Implementationpublic:BOOL SetItemState( HTREEITEM hItem, UINT nState, UINT nStateMask, BOOL bSearch=TRUE);virtual ~CMutiTreeCtrl();// Generated message map functionsprotected://{{AFX_MSG(CMutiTreeCtrl)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnStateIconClick(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);//}}AFX_MSGDECLARE_MESSAGE_MAP()private:UINT m_uFlags;void TravelSiblingAndParent(HTREEITEM hItem, int nState);void TravelChild(HTREEITEM hItem,int nState);};二、重载CTreeCtrl的SetItemState()函数,在调用了基类的SetItemState()函数修改了节点状态以后,遍历一遍当前节点子节点、兄弟节点、父节点,按照上述逻辑修改为相应的状态,实现三态显示。
调用此函数有二种情况:①键盘或鼠标输入修改节点状态,此时要遍历全部父、兄、子节点;②程序根据实际情况调用修改节点状态,因为修改节点状态时是判断了全部子节点的状态后得出了状态,所以此时仅需要遍历全部的兄、父节点,更改其状态符合逻辑。
故在重载的函数后面加了一个缺省为TRUE的bSearch变量,当程序修改节点时请置此标志为FALSE。
BOOL CMutiTreeCtrl::SetItemState(HTREEITEM hItem, UINT nState,UINT nStateMask, BOOL bSearch){BOOL bReturn=CTreeCtrl::SetItemState( hItem, nState, nStateMask );UINT iState = nState >> 12;if(iState!=0){if(bSearch) TravelChild(hItem, iState);TravelSiblingAndParent(hItem,iState);}return bReturn;}三、检测鼠标单击节点CHeckBox的事件,更改对应的节点状态并遍历树的其他节点。
void CMutiTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point){HTREEITEM hItem =HitTest(point, &m_uFlags);if ( (m_uFlags&TVHT_ONITEMSTATEICON )){//nState: 0->无选择钮1->没有选择2->部分选择3->全部选择UINT nState = GetItemState( hItem,TVIS_STATEIMAGEMASK ) >> 12;nState=(nState==3)?1:3;SetItemState(hItem,INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGE MASK);}CTreeCtrl::OnLButtonDown(nFlags, point);}void CMutiTreeCtrl::OnStateIconClick(NMHDR* pNMHDR, LRESULT* pResult){if(m_uFlags&TVHT_ONITEMSTATEICON) *pResult=1;else *pResult = 0;}四、检测键盘按空格键的事件,更改对应的节点状态并遍历树的其他节点。
void CMutiTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){//处理空格键if(nChar==0x20){HTREEITEM hItem =GetSelectedItem();UINT nState = GetItemState( hItem,TVIS_STATEIMAGEMASK ) >> 12;if(nState!=0){nState=(nState==3)?1:3;SetItemState( hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );}}else CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);}五、树的遍历用递归的方法搜索当前节点的父、兄、子节点①递归搜索子节点void CMutiTreeCtrl::TravelChild(HTREEITEM hItem, int nState){HTREEITEM hChildItem,hBrotherItem;//查找子节点,没有就结束hChildItem=GetChildItem(hItem);if(hChildItem!=NULL){//设置子节点的状态与当前节点的状态一致CTreeCtrl::SetItemState(hChildItem,INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK );//再递归处理子节点的子节点和兄弟节点TravelChild(hChildItem, nState);//处理子节点的兄弟节点和其子节点hBrotherItem=GetNextSiblingItem(hChildItem);while (hBrotherItem){//设置子节点的兄弟节点状态与当前节点的状态一致int nState1 = GetItemState( hBrotherItem,TVIS_STATEIMAGEMASK ) >> 12;if(nState1!=0){CTreeCtrl::SetItemState( hBrotherItem,INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK );}//再递归处理子节点的兄弟节点的子节点和兄弟节点TravelChild(hBrotherItem, nState);hBrotherItem=GetNextSiblingItem(hBrotherItem);}}}②递归搜索兄、父节点voidCMutiTreeCtrl::TravelSiblingAndParent(HTREEITEM hItem, int nState) {HTREEITEM hNextSiblingItem,hPrevSiblingItem,hParentItem;//查找父节点,没有就结束hParentItem=GetParentItem(hItem);if(hParentItem!=NULL){int nState1=nState;//设初始值,防止没有兄弟节点时出错//查找当前节点下面的兄弟节点的状态hNextSiblingItem=GetNextSiblingItem(hItem);while(hNextSiblingItem!=NULL){nState1 = GetItemState( hNextSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;if(nState1!=nState && nState1!=0) break;elsehNextSiblingItem=GetNextSiblingItem(hNextSiblingItem);}if(nState1==nState){//查找当前节点上面的兄弟节点的状态hPrevSiblingItem=GetPrevSiblingItem(hItem);while(hPrevSiblingItem!=NULL){nState1 =GetItemState(hPrevSiblingItem,TVIS_STATEIMAGEMASK)>> 12;if(nState1!=nState && nState1!=0) break;elsehPrevSiblingItem=GetPrevSiblingItem(hPrevSiblingItem);}if(nState1==nState || nState1==0){nState1 = GetItemState( hParentItem,TVIS_STATEIMAGEMASK ) >> 12;if(nState1!=0){//如果状态一致,则父节点的状态与当前节点的状态一致CTreeCtrl::SetItemState( hParentItem,INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK );}//再递归处理父节点的兄弟节点和其父节点TravelSiblingAndParent(hParentItem,nState);}else{//状态不一致,则当前节点的父节点、父节点的父节点……状态均为第三态hParentItem=GetParentItem(hItem);while(hParentItem!=NULL){nState1 = GetItemState( hParentItem,TVIS_STATEIMAGEMASK ) >> 12;if(nState1!=0){CTreeCtrl::SetItemState( hParentItem,INDEXTOSTATEIMAGEMASK(2),TVIS_STATEIMAGEMASK );}hParentItem=GetParentItem(hParentItem);}}}}好了,一切就是这么简单,如果你还不清楚的话,那就打开工程看看吧,如你有什么问题也不要忘记来信告诉我哦!最后祝大家学习愉快,多多交流,多多进步,一切顺利!。