建立一个方便刷题调试的二叉树(VS2019环境)
在刷数据结构和算法的题的时候,涉及到二叉树的部分,比如镜像反转二叉树、判断平衡二叉树等等,往往需要一些现成的二叉树来进行测试。而创建一个二叉树比较麻烦,而且没法实时观察到各节点数据的分布情况。这里我借鉴牛客网的方法,将二叉树序列化成一个数组来表示
这是牛客网的说明,我这里简化了下,把‘#’换成NULL也就是0来代表空节点。
将节点和二叉树以及一些操作都写进了类模板里,在Tree类的构造函数中实现了二叉树的构造,构造函数的参数为装有序列化数组的vector容器。构造函数中通过一个辅助队列和一个迭代器实现二叉树的层次遍历顺序的构造,辅助队列里装的是TreeNode*节点型数据。
先将根节点入队,然后设立一个循环,从根节点开始,每次出队队首元素就相应得创建两个节点并将它们入队,同时根据迭代器递增的遍历值来初始化节点元素,循环的结束条件是迭代器到达容器末端。
这样,一个二叉树就通过给定的序列化数组创建了。
同时,类中还有计算树高和每个节点深度的成员函数,都是用递归实现,这里不做详细介绍。
#pragma once
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
template <typename T>
class TreeNode
{
public:
TreeNode<T>* leftChild;
TreeNode<T>* rightChild;
TreeNode<T>* parent;
T e;
int depth = 0;
TreeNode(const T& elem) :e(elem)
{
leftChild = rightChild = parent = NULL;
}
//获取该节点树高
int GetHeight()
{
int h1 = (leftChild != NULL) ? leftChild->GetHeight() : 0;
int h2 = (rightChild != NULL) ? rightChild->GetHeight() : 0;
return (h1 > h2 ? h1 : h2) + 1;
}
//初始每个节点的深度
void initdepth()
{
if (leftChild != NULL)
{
leftChild->depth = this->depth + 1;
leftChild->initdepth();
}
if (rightChild != NULL)
{
rightChild->depth = this->depth + 1;
rightChild->initdepth();
}
return;
}
};
template <typename T>
class Tree
{
public:
//根节点
TreeNode<T>* Root = NULL;
vector<T> v_t;
//根据vector的元素,以层次遍历的方式建立一个二叉树
//定义一个迭代器iter遍历vector容器
//利用队列的性质,先将根节点入队,然后每次迭代中创建队首的左右子树(iter相应后移,判断iter是否越界),并将左右子树的根节点分别放进队列
//vector中的NULL代表空字节点,参考牛客网TreeNode格式说明,如下是{1,2,3,NULL,NULL,4,NULL,NULL,5}的转换
// 1
// / \
// 2 3
// /
// 4
// \
// 5
template<typename VST>
Tree(vector<VST>& V)
{
v_t.assign(V.begin(), V.end());
if (V.empty())
return;
TreeNode<VST>* root = new TreeNode<VST>(V[0]);
queue<TreeNode<VST>*> Q;
Q.push(root);
//函数模板里定义泛型的迭代器vector<VST>::iterator,需要在前面加上typename
typename vector<VST>::iterator iter = V.begin(); iter++;
while (iter != V.end())
{
if (*iter != NULL)
{
TreeNode<VST>* temp1 = new TreeNode<VST>(*(iter++));
Q.front()->leftChild = temp1; temp1->parent = Q.front(); Q.push(temp1);
}
else
iter++;
if (iter != V.end())
{
if (*iter != NULL)
{
TreeNode<VST>* temp2 = new TreeNode<VST>(*(iter++));
Q.front()->rightChild = temp2; temp2->parent = Q.front(); Q.push(temp2);
}
else
iter++;
}
Q.pop();
}
Root = root;
}
//获取树高
int GetHeight()
{ return Root->GetHeight(); }
};
将这段代码命名成头文件Tree.h,在.cpp中包含头文件,主函数如下
#inlcude"Tree.h"
int main()
{
vector<int> vec({ 1,2,3,4,5,0,0,0,0,6 });
Tree<int> T0(vec);
cout << T0.GetHeight();
T0.Root->initdepth();
system("pause");
return 0;
}
调试-全部中断后可在变量窗口观察到节点数据的分布,经检验与预期的二叉树一致
代码可能还有不足和bug,若发现请指正!