template
class BNode {//创建二叉树结点类
public:
T data;//存储数据
BNode* leftchild, * rightchild;//创建该结点的左右孩子指针
BNode(T mydata = T())://二叉树结点类初始化
leftchild(nullptr), rightchild(nullptr),data(mydata){}
friend int IsExistLf(BNode* Node)//判断该结点是否有左孩子,如果有取出其数据
{
if (Node->leftchild == nullptr)
return 0;
cout << Node->leftchild->data << endl;
return 1;
}
friend int IsExistRt(BNode* Node)//判断该结点是否有左孩子,如果有取出其数据
{
if (Node->rightchild == nullptr)
return 0;
cout << Node->rightchild->data << endl;
return 1;
}
};
这里的IsExistRt函数仅仅是为了测试用,其余没什么用
template
class BinaryTreeLinkedList
{
public:
BinaryTreeLinkedList();
BNode* Creat(BNode* root);//初始化一棵二叉树,其前序序列由键盘输入BinaryTreeLinkedList;
BNode* CreateTree(T* a, size_t n, const T& invalid, size_t& index);
//BNode* Create(BNode* root);
~BinaryTreeLinkedList();//析构函数,释放二叉链表中各结点的存储空间
void SetRecursiveFlag(bool ret);//设置RecursiveFlag
void PreOrder(BNode* root);//前序遍历二叉树
void InOrder(BNode* root);//中序遍历二叉树
void PostOrder(BNode* root);//后序遍历二叉树
void Levelorder(BNode* root);//层序遍历二叉树
int Depth(BNode* root);//返回二叉树的深度
int LeafNodeNum(BNode* root);//返回二叉树叶子结点的个数
int AllNodeNum(BNode* root);//返回二叉树所有结点的个数
private:
static int num;
BNode* root;//指向根结点的头指针
bool RecursiveFlag; //RecursiveFlag是指采用递归编写遍历,当为false时采用循环编写遍历
void Release(BNode* root);//析构函数调用
};
这里的Creat函数与CreatTree函数均编写有问题,用该方法创建的子树仅会有根结点,并且根节点的左右节点会变成空。
BinaryTreeLinkedList myBT;
BNode* root = nullptr;
root = myBT.Creat(root);
cout << IsExistLf(root) << endl;
cout << IsExistRt(root) << endl;
我在测试时无论cin采用一次性输完字符串还是一个一个输入字符,最后都发现,递归进去了(内存已经建立了),但是各个有数据的结点没有指针关系,猜测Creat函数的问题,由于是cin输入数据,而我使用的模板是char型,不管怎么输入,系统都认为他是个字符串,地址一直没变过。
#pragma once
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include
#include//用栈和循环模拟递归
#include
#include
using std::cout;
using std::cin;
using std::endl;
using std::stack;
using std::deque;
template
class BNode {//创建二叉树结点类
public:
T data;//存储数据
BNode* leftchild, * rightchild;//创建该结点的左右孩子指针
BNode(T mydata = T())://二叉树结点类初始化
leftchild(nullptr), rightchild(nullptr),data(mydata){}
friend int IsExistLf(BNode* Node)//判断该结点是否有左孩子,如果有取出其数据
{
if (Node->leftchild == nullptr)
return 0;
cout << Node->leftchild->data << endl;
return 1;
}
friend int IsExistRt(BNode* Node)//判断该结点是否有左孩子,如果有取出其数据
{
if (Node->rightchild == nullptr)
return 0;
cout << Node->rightchild->data << endl;
return 1;
}
};
template
class BinaryTreeLinkedList
{
public:
BinaryTreeLinkedList();
BNode* Creat(BNode* root);//初始化一棵二叉树,其前序序列由键盘输入BinaryTreeLinkedList;
BNode* CreateTree(T* a, size_t n, const T& invalid, size_t& index);
//BNode* Create(BNode* root);
~BinaryTreeLinkedList();//析构函数,释放二叉链表中各结点的存储空间
void SetRecursiveFlag(bool ret);//设置RecursiveFlag
void PreOrder(BNode* root);//前序遍历二叉树
void InOrder(BNode* root);//中序遍历二叉树
void PostOrder(BNode* root);//后序遍历二叉树
void Levelorder(BNode* root);//层序遍历二叉树
int Depth(BNode* root);//返回二叉树的深度
int LeafNodeNum(BNode* root);//返回二叉树叶子结点的个数
int AllNodeNum(BNode* root);//返回二叉树所有结点的个数
private:
static int num;
BNode* root;//指向根结点的头指针
bool RecursiveFlag; //RecursiveFlag是指采用递归编写遍历,当为false时采用循环编写遍历
void Release(BNode* root);//析构函数调用
};
template
int BinaryTreeLinkedList::num = 0;
template
BinaryTreeLinkedList::BinaryTreeLinkedList() :root(nullptr), RecursiveFlag(true)
{
}
//初始化一棵二叉树,其前序序列由键盘输入BinaryTreeLinkedList;
template
BNode* BinaryTreeLinkedList::Creat(BNode* root)
{
char ch;
//cin.get(ch);
cin >> ch;
//if (ch == '#')
// //root = nullptr;
//else
//{
// root = new BNode(ch);
// //root->data = ch;
// cout << "数据为: " << root->data << "地址为: " << root << endl;
// Creat(root->leftchild);
// Creat(root->rightchild);
//}
if ((ch != '#'))
{
root = new BNode(ch);
cout << "数据为: " << root->data << "地址为: " << root << endl;
Creat(root->leftchild);
Creat(root->rightchild);
}
return root;
}
template
BNode* BinaryTreeLinkedList::CreateTree(T* a, size_t n, const T& invalid, size_t& index)
{
//BNode* root = nullptr;
if (a[index] != invalid)
{
root = new BNode(a[index]);
//root->data = a[index];
cout << "数据为: " << root->data << "地址为: " << root << endl;
root->leftchild = CreateTree(a, n, invalid, ++index);
root->rightchild = CreateTree(a, n, invalid, ++index);
}
return root;
}
//析构函数,释放二叉链表中各结点的存储空间
template
BinaryTreeLinkedList::~BinaryTreeLinkedList()
{
Release(root);
}
//设置RecursiveFlag
template
void BinaryTreeLinkedList::SetRecursiveFlag(bool ret)
{
RecursiveFlag = ret;
}
//前序遍历二叉树
//若二叉树为空,则空操作返回,否则
//(1)访问根结点;
//(2)前序遍历根结点的左子树;
//(3)前序遍历根结点的右子树。
template
void BinaryTreeLinkedList::PreOrder(BNode* root)
{
if (RecursiveFlag)//采用递归遍历
{
if (!root)
return;
else
{
//++num;
cout << root->data << " ";
PreOrder(root->leftchild);
PreOrder(root->rightchild);
}
}
else //采用栈和循环遍历
{
stack*> mystack;//创建一个可以存储二叉树结点的栈
if (root)
{
////循环前的初始化
//mystack.push(root);//将根结点压入栈中
//cout << root->data << " ";
//root = root->leftchild;
while (root || !mystack.empty())//当当前结点不为空或者栈不空都应执行循环
{
while (root)//如果此时该结点的左孩子不为空指针,那么要继续压栈
{
mystack.push(root);
cout << root->data << " ";//打印当前结点信息
root = root->leftchild;
}
if (!mystack.empty())//此时该结点的左孩子为空指针,那么我们需要访问该结点的右孩子
{
root = mystack.top();//获取当前结点的指针
root = root->rightchild;
mystack.pop();//此结点的弹出,它的信息已经全部利用完了(左右孩子都访问了一遍所以他没有利用价值了)
}
}
}
}
}
//中序遍历二叉树
//若二叉树为空,则空操作返回,否则
//(1)中序遍历根结点的左子树;
//(2)访问根结点;
//(3)中序遍历根结点的右子树。
template
void BinaryTreeLinkedList::InOrder(BNode* root)
{
if (RecursiveFlag)//采用递归遍历
{
if (root)
{
PreOrder(root->leftchild);
cout << root->data << " ";
PreOrder(root->rightchild);
}
else
return;
}
else //采用栈和循环遍历
{
stack*> mystack;//创建一个可以存储二叉树结点的栈
if (root)
{
while (root || !mystack.empty())
{
while (root)//只进行压栈和结点向左伸展
{
mystack.push(root);
root = root->leftchild;
}
if (!mystack.empty())//当左孩子为空时,需要打印该结点的信息,同时访问该结点的右孩子
{
root = mystack.top();//获取当前结点的指针
cout << root->data << " ";//打印当前最左侧结点的信息
root = root->rightchild;
mystack.pop();//出栈
}
}
return;
}
return;
}
}
//后序遍历二叉树
//若二叉树为空,则空操作返回,否则
//(1)后序遍历根结点的左子树;
//(2)后序遍历根结点的右子树;
//(3)问根结点。
template
void BinaryTreeLinkedList::PostOrder(BNode* root)
{
if (RecursiveFlag)//采用递归遍历
{
if (root)
{
PostOrder(root->leftchild);
PostOrder(root->rightchild);
cout << root->data << " ";
}
else
return;
}
else //采用循环遍历
{
//stack*> mystack;//创建一个可以存储二叉树结点的栈
//if (root)
//{
// while (root || mystack.size() != 1)//当当前结点不为空或者栈不空都应执行循环
// {
// while (root)//如果此时该结点的左孩子不为空指针,那么要继续压栈
// {
// mystack.push(root);
// root = root->leftchild;
// }
// if (!mystack.empty())//此时该结点的左孩子为空指针,那么我们需要访问该结点的右孩子
// {
// if (mystack.size() != 1&&root->rightchild)
// {
// root = mystack.top();//获取当前结点的指针
// cout << root->data << " ";//打印当前最左侧结点的信息
// root = root->rightchild;
// mystack.pop();//出栈
// }
// else//说明现在仅剩下根结点了
// {
// root = mystack.top();
// root = root->rightchild;
// }
// }
// }
// root = mystack.top();//访问最后一个结点根结点
// cout << root->data << " ";
// mystack.pop();
// return;
//}
//return;
}
}
//层序遍历二叉树
template
void BinaryTreeLinkedList::Levelorder(BNode* root)
{
deque*> mydeque;
if (root)
{
//循环起端初始化
mydeque.push_back(root);
while (!mydeque.empty())//当队列不空时要继续出队和入队,因为队列先进先出
{
root = mydeque.front();//取出队列队头元素
cout << root->data << " ";
mydeque.pop_front();//出队
if (root->leftchild) {
mydeque.push_back(root->leftchild);
}
if (root->rightchild) {
mydeque.push_back(root->rightchild);
}
}
}
return;
}
//返回二叉树的深度
template
int BinaryTreeLinkedList::Depth(BNode* root)
{
if (root)
{
int dpt1 = Depth(root->leftchild);//获取当前结点的左子树深度
int dpt2 = Depth(root->rightchild);//获取当前结点的右子树深度
return (dpt1 > dpt2) ? (dpt1 + 1) : (dpt2 + 1);//仅选择当前最深的数值+基础值1,根结点默认深度为1
}
else
return 0;
}
//返回二叉树叶子结点的个数
template
int BinaryTreeLinkedList::LeafNodeNum(BNode* root)
{
if (root == nullptr)
return 0;
else if (root->leftchild == nullptr && root->rightchild == nullptr)
return 1;
else
return LeafNodeNum(root->leftchild) + LeafNodeNum(root->rightchild);
}
//返回二叉树所有结点的个数
template
int BinaryTreeLinkedList::AllNodeNum(BNode* root)
{
if (root == nullptr)
return 0;
else
return AllNodeNum(root->leftchild) + AllNodeNum(root->rightchild) + 1;
}
//析构函数调用
template
void BinaryTreeLinkedList::Release(BNode* root)
{
if (root)//如果当前结点不为空时,则进入递归
{
Release(root->leftchild);//释放左子树
Release(root->rightchild);//释放右子树
delete root;
}
return;
}
#endif // !BINARYTREE_
#include
#include"binary_tree.h"
int main()
{
BinaryTreeLinkedList myBT;
BNode* root = new BNode('A');//按照前序遍历创建节点
root->leftchild= new BNode('B');
root->leftchild->rightchild = new BNode('D');
root->rightchild = new BNode('C');
cout << "树的深度为:" << myBT.Depth(root) << endl;
cout << "树的叶子结点个数为:" << myBT.LeafNodeNum(root) << endl;
cout << "树的所有结点个数为:" << myBT.AllNodeNum(root) << endl;
//myBT.SetRecursiveFlag(false);
cout << "递归前序遍历:" << endl;
myBT.PreOrder(root);
cout << endl;
cout << "递归中序遍历:" << endl;
myBT.InOrder(root);
cout << endl;
cout << "递归后序遍历:" << endl;
myBT.PostOrder(root);
cout << endl;
cout << "层序遍历:" << endl;
myBT.Levelorder(root);
cout << endl;
myBT.SetRecursiveFlag(false);
cout << "栈与循环前序遍历:" << endl;
myBT.PreOrder(root);
//cout << endl;
//cout << "栈与循环中序遍历:" << endl;
//myBT.InOrder(root);
//cout << endl;
cout << endl;
//size_t index = 0;
//char x[9] = { 'A','B','#','D','#','#','C','#','#' };
//root = myBT.CreateTree(x, sizeof(x) / sizeof(char), '#', index);
//root = myBT.Creat(root);
//cout << IsExistLf(root) << endl;
//cout << IsExistRt(root) << endl;
}
树的深度为:3
树的叶子结点个数为:2
树的所有结点个数为:4
递归前序遍历:
A B D C
递归中序遍历:
B D A C
递归后序遍历:
D B C A
层序遍历:
A B C D
栈与循环前序遍历:
A B D C
由于我的创建子树函数有问题,测试时我自己手动创建的二叉树结点