MFC动态建立二叉树、序列检错以及获取父节点

根据前序+中序或中序+后序在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 
  • 22
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值