1树的可视化实现1、MFC工程创建在文档/视图结构应用程序中,可以通过MFCAppWizard创建一个新工程,实现可视化数据结构窗口实例。下面制作一个基于单文档的MFC应用程序。1.选择File-New菜单命令,弹出New窗口中选择Projects选项卡,选择“MFC应用程序”项,在“名称”编辑框中输入工程名DataStructVisual_Tree,在“位置”编辑框中设置工程文件存放的位置为“D:\DataStructVisual_VS2015\”,如图1所示。图1新建MFC工程窗口图2MFC应用程序向导窗口图3MFCAppWizard向导窗口2.单击“确定”按钮,弹出“MFC应用程序向导”窗口,如图2所示。在“MFCAppWizard”窗口中可以指定生成框架的概述。3.单击“下一步”,弹出“MFC应用程序向导”,按照图3所示选择选项,生成单文档应用程序DataStructVisual。Singledocument:生成单文档应用程序框架。Multipledocument:生成多文档应用程序框架。Dialogbased:生成基于对话框的应用程序框架。Document/Viewarchitecturesupport:该选项允许生成文档/视图和非文档/视图结构程序。2图4MFCAppWizard向导逐步配置情况4.单击“完成”按钮,生成单文档应用程序DataStructVisual_Tree,如图5所示。3图5新建单文档应用程序DataStructVisual_Tree5.单击“本地Windows调试器”按钮,弹出窗口,如图6所示。图6单文档应用程序DataStructVisual_Tree运行结果2、二叉树类的创建1.右键单击类视图的根结点,在弹出的窗口选择“添加|类”,然后在弹出“一般C++类向4导”对话框中将新类命名为CBiTreeNode,基类为CObject,如图7所示。5图7类CBiTreeNode新建窗口2.单击“完成”按钮。在类CBiTreeNode的头文件BiTreeNode.h中添加如下代码:#includeafx.hclassCBiTreeNode:publicCObject{public:CBiTreeNode();~CBiTreeNode();boolDrawBiTreeNode(CDC*pDC);//绘制二叉树结点voidDrawSearchBITreeNode(intvBiTreeKey,CDC*pDC);//绘制查找结点public:CPointm_Point;//二叉树结点坐标位置COLORREFm_Color;//二叉树结点颜色CStringm_StrName;//二叉树结点名称intm_Value;//二叉树结点值BOOLm_Visit;//二叉树结点是否访问CPointm_DisplayPoint;//二叉树新的显示位置//二叉树结点左右孩子指针和父结点指针CBiTreeNode*m_pLChild,*m_pRChild,*m_pParent;intm_Leftwidth;//二叉树左子树宽度6intm_Rightwidth;//二叉树右子树宽度};3.类CBiTreeNode的源文件BiTreeNode.cpp中添加如下代码:boolCBiTreeNode::DrawBiTreeNode(CDC*pDC){CPentDrawPen,*tPOldPen;CRecttNodeRect;CStringtStr;tStr.Format(_T(%d),m_Value);tDrawPen.CreatePen(PS_SOLID,1,m_Color);tPOldPen=pDC-SelectObject(&tDrawPen);tNodeRect.SetRect(m_Point.x-20,m_Point.y-20,m_Point.x+20,m_Point.y+20);if(!pDC-Ellipse(tNodeRect))returnfalse;if(!pDC-TextOut(m_Point.x-10,m_Point.y-10,tStr))returnfalse;pDC-SelectObject(tPOldPen);returntrue;}voidCBiTreeNode::DrawSearchBITreeNode(intvBiTreeKey,CDC*pDC){CPentPen;CRecttNodeRect;TEXTMETRICtTxt;CStringtStr;tPen.CreatePen(1,2,RGB(255,0,0));CPen*tPOldPen=pDC-SelectObject(&tPen);tStr.Format(_T(%d),vBiTreeKey);pDC-GetTextMetrics(&tTxt);tNodeRect.SetRect(m_Point.x-20,m_Point.y-20,m_Point.x+20,m_Point.y+20);pDC-Ellipse(tNodeRect);pDC-TextOut(m_Point.x-10,m_Point.y-10,tStr);pDC-SelectObject(tPOldPen);}4.右键单击类视图的根结点,在弹出的窗口选择“添加|类”,然后在弹出“一般C++类向导”对话框中将新类命名为CBiTree,如下图8所示。7图8类CBiTree新建窗口5.在类CBiTree的头文件BiTree.h中添加如下代码:#includemath.h#includeafxtempl.h#includeafxwin.h#includeafxext.h#includeBiTreeNode.h#includestackusingnamespacestd;6.定义类CBiTree的成员变量和成员函数,CBiTree类成员方法的声明,它们保存在CBiTree.h头文件中。classCBiTree{public:CBiTree();~CBiTree();voidInsertBiTreeNode(CRectvWinRect,intvBTNValue);//二叉树中插入关键字函数voidInsertBiTreeNode(CBiTreeNode*(&vPBiTreeNode),CBiTreeNode*(&vPNewBTNode),intvBTNValue);//重载二叉树插入关键字函数8voidDeleteBiTreeNode(CRectvWinRect,intvBTNValue);//二叉树删除关键字函数voidDeleteBiTreeNode(CBiTreeNode*vPBTRoot,intvBTNValue);//重载二叉树删除关键字函数voidSetNewPositions(CBiTreeNode*vPBiTree,intXposition,intposition);//设置二叉树结点显示位置函数voidSetBiTreeSearchKey(intvBTNValue);//设置二叉树待查关键字函数voidReSizeTree();//结点间距离计算函数CBiTreeNode*SearchBiTreeNode(CBiTreeNode*vPBTree,intvBTNValue);//二叉树关键字查找函数voidChangeHeights(CBiTreeNode*(&vPBTRoot));//计算二叉树结点高度intResetWidths(CBiTreeNode*vPBTRoot);//计算二叉树显示宽度voidDrawBiTree(CRectvWinRect,CDC*pDC);//绘制二叉树函数voidDrawBiTree(CBiTreeNode*vPBiTreeNode,CDC*pDC);//重载绘制二叉树函数voidDrawBiTreeNode(CBiTreeNode*vPBiTreeNode,CDC*pDC);//绘制二叉树结点函数voidDrawBiTreeLine(CBiTreeNode*vPBiTreeNode,CDC*pDC);//绘制二叉树分支函数voidDrawSearchBiTreeNode(CDC*pDC);//绘制二叉树查找结点函数voidUnRecPreOrderTraverse(CBiTreeNode*vPBiTreeRoot);voidUnRecInOrderTraverse(CBiTreeNode*vPBiTreeRoot);voidUnRecPostOrderTraverse(CBiTreeNode*vPBiTreeRoot);private:CBiTreeNode*m_pBiTreeRoot;//二叉树根结点指针CRectm_WinSize;//当前窗口尺寸intm_SearchValue;//二叉树待查找值CTypedPtrListCObList,CBiTreeNode*m_BiTreeContainer;//二叉树遍历存储容器intm_Visit;};7.下面介绍CBiTree类成员方法的代码实现,它们均保存在BiTree.cpp源文件中。CBiTree::CBiTree(){m_pBiTreeRoot=NULL;}CBiTree::~CBiTree(){}voidCBiTree::DrawBiTree(CRectvWinRect,CDC*pDC){9if(m_pBiTreeRoot){DrawBiTree(m_pBiTreeRoot,pDC);}}voidCBiTree::DrawBiTree(CBiTreeNode*vPBiTreeNode,CDC*pDC){DrawBiTreeLine(vPBiTreeNode,pDC);DrawBiTreeNode(vPBiTreeNode,pDC);}voidCBiTree::DrawBiTreeNode(CBiTreeNode*vPBiTreeNode,CDC*pDC){vPBiTreeNode-DrawBiTreeNode(pDC);if(vPBiTreeNode-m_pLChild){DrawBiTreeNode(vPBiTreeNode-m_pLChild,pDC);}if(vPBiTreeNode-m_pRChild){DrawBiTreeNode(vPBiTreeNode-m_pRChild,pDC);}}voidCBiTree::DrawBiTreeLine(CBiTreeNode*vPBiTreeNode,CDC*pDC){if(vPBiTreeNode-m_pLChild){pDC-MoveTo(vPBiTreeNode-m_Point);pDC-LineTo(vPBiTreeNode-m_pLChild-m_Point);DrawBiTreeLine(vPBiTreeNode-m_pLChild,pDC);}if(vPBiTreeNode-m_pRChild){pDC-MoveTo(vPBiTreeNode-m_Point);pDC-LineTo(vPBiTreeNode-m_pRChild-m_Point);DrawBiTreeLine(vPBiTreeNode-m_pRChild,pDC);}}voidCBiTree::InsertBiTreeNode(CRectvWinRect,intvBTNValue){m_WinSize=vWinRect;CStringtStr;tStr.Format(_T(%d),vBTNValue);if(!m_pBiTreeRoot)10{CPointtCurPoint;m_pBiTreeRoot=newCBiTreeNode();m_pBiTreeRoot-m_Visit=FALSE;m_pBiTreeRoot-m_StrName=tStr;m_pBiTreeRoot-m_Value=vBTNValue;m_pBiTreeRoot-m_