根据前序+中序或中序+后序在MFC中实现动态建立二叉树。
前言
在上一篇博客中,我分享了如何根据前序、后序、前序+中序、中序+后序建立二叉树。今天来分享一下如何在MFC中动态建立二叉树,并且具有序列检错机制和查询父节点功能。
功能展示:
一、动态建立二叉树
1.题目要求
2.具体实现
1.对话框布局
上面的控件是PictureControl控件
2.二叉树节点和二叉树类的定义
1.二叉树结点
// 定义在BinaryTree.h头文件中
#pragma once
#include<iostream>
using namespace std;
template <class T>
struct BinTNode
{
T data; //节点数据
CPoint point; //每个节点的位置
BinTNode<T>* lchild, * rchild, * parent;
BinTNode() :lchild(NULL), rchild(NULL), parent(NULL) {
}
BinTNode(T x, BinTNode<T>* l = NULL, BinTNode<T>* r = NULL)
:data(x), lchild(l), rchild(r), parent(NULL) {
}
};
2.二叉树类
// 定义在BinaryTree.h头文件中
template <class T>
class BinaryTree
{
protected:
BinTNode<T>* root;
public:
BinaryTree() :root(NULL) {
}
~BinaryTree() {
DestroyTree(root); }
BinTNode<T>* GetRoot() {
return root; }//取得根节点的地址
void DestroyTree(BinTNode<T>* tree); //删除一颗树
void CreateBinTree1(BinTNode<T>*& tree1, BinTNode<T>*& tree2, char* pre, char* in, int n, long x, long y);//根据前序+中序建立二叉树
void CreateBinTree2(BinTNode<T>*& tree1, BinTNode<T>*& tree2, char* in, char* post, int n, long x, long y);//根据中序+后序建立二叉树
BinTNode<T>* SearchParentNode(BinTNode<T>*& tree, T data);//从结点tree开始搜索值为data的节点,返回该节点的父节点
void AdjustTree(BinTNode<T>* tree, int op);//调整树中结点位置
int Height(BinTNode<T>* tree);//求树高
};
3.打印二叉树
思路:
首先,根据前序+中序(或中序+后序)建立一颗二叉树。然后打印这棵树。难点在于如何打印这棵树,以及打印时的布局。接下来我会详细讲如何打印,以及节点如何布局。
关于打印二叉树:我选择了在一个PictureControl控件中打印。首先获得该控件的画布,以及控件大小。
// 获取控件画布以及控件大小,设置画笔
CRect rect;
CWnd* pWin = GetDlgItem(IDC_STATIC);
pWin->GetClientRect(rect);//获取控件大小
int x = rect.Width();//x即控件宽度
int y = rect.Height();//y即控件高度
CDC* pDC = pWin->GetDC();//获取控件画布
CPen pen(PS_SOLID, 3, RGB(255, 0, 0));//创建画笔
pDC->SelectObject(&pen);//选择画笔
我使用了递归画树的方法。函数参数有两个,一个是画家CDC*pDC,另一个是开始节点tree。
打印节点的操作非常简单,只需要以节点位置为圆心画圆,再在该位置打印节点元素值即可。接下来就是递归,画这个节点的左子树和右子树,然后每画一个节点,就将对应根节点与之相连。
而要实现动态建立,只需要添加Sleep(time)函数即可。Sleep(time)函数就是让程序暂停time毫秒。
// 二叉树打印函数
void CCreateBinaryTreeByMFCDlg::PrintBinaryTree(CDC* pDC, BinTNode<char>* tree)
{
// TODO: 在此处添加实现代码.
if (tree == NULL) return;
pDC->Ellipse(tree->point.x - 25, tree->point.y - 25, tree->point.x + 25, tree->point.y + 25);
Sleep(200);
CString str;
str.Format(_T("%c"), tree->data);
pDC->TextOutW(tree->point.x, tree->point.y, str);
Sleep(200);
if (tree->lchild != NULL)
{
PrintBinaryTree(pDC, tree->lchild);
Sleep(200);
//连接根节点和该节点
pDC->MoveTo(tree->point.x, tree->point.y);
pDC->LineTo(tree->lchild->point.x, tree->lchild->point.y);
}
if (tree->rchild