//头文件
//BinaryTreeNode.h
#ifndef BINARYTREENODE_H
#define BINARYTREENODE_H
template<typename T>
class BinaryTreeNode{
public:
BinaryTreeNode<T>* leftChild;
BinaryTreeNode<T>* rightChild;
T data;
BinaryTreeNode(){
}
BinaryTreeNode(const T& val, BinaryTreeNode<T>* str, BinaryTreeNode<T>* ptr) :data(val), leftChild(str), rightChild(ptr){
}
};
#endif
//BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include"BinaryTreeNode.h"
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
template<typename T>
class BinaryTree{
private:
BinaryTreeNode<T>* root;
public:
BinaryTree();
~BinaryTree();
void simulate();
private:
void CreatTree();
void Print();
void Clear(BinaryTreeNode<T>* &str);
void CreatLeaf(BinaryTreeNode<T>* &str);
void PrintIoder(BinaryTreeNode<T>* str)const;
//遍历二叉树,获得度为1的节点数
int NodeOne(BinaryTreeNode<T>* str);
int NodeOne();
//遍历二叉树,获得度为2的节点个数
int NodeTwo(BinaryTreeNode<T>* str);
int NodeTwo();
//遍历二叉树,获得叶子节点的个数
int NodeLeaf(BinaryTreeNode<T>* str);
int NodeLeaf();
//树的高度问题
int Height(BinaryTreeNode<T>* str);
int Height();
//树的宽度问题,获得节点数最多的一层上的节点总数
void CountLine(BinaryTreeNode<T>* str, int* ptr, int i);
int FindMaxLine();//关于求宽度的递归函数的辅助函数
int CountLine();
//遍历二叉树,获得最大元素值
void FindMaxValue(BinaryTreeNode<T>* str,T& val);
T FindMaxValue();
//遍历二叉树,交换节点的左孩子右孩子
void ChangLeftRight(BinaryTreeNode<T>* str);
void ChangLeftRight();
//遍历二叉树,删除所有的叶子节点
void DeleteLeaf(BinaryTreeNode<T>* &str);
//第六题判断二叉树是否为完全二叉树
bool isCompleteTree()const;
int NodeNumber()const;
};
template<typename T>
BinaryTree<T>::BinaryTree()
{
this->root = NULL;
}
template<typename T>
BinaryTree<T>::~BinaryTree()
{
this ->Clear(this->root);
}
template<typename T>
void BinaryTree<T>::Clear(BinaryTreeNode<T>* &str)
{
if (str)
{
Clear(str->leftChild);
Clear(str->rightChild);
delete str;
}
str = NULL;
}
template<typename T>
void BinaryTree<T>::CreatTree()
{
this->CreatLeaf(this->root);
}
template<typename T>
void BinaryTree<T>::CreatLeaf(BinaryTreeNode<T>* &str)
{
T value;
if (this->root == NULL)
{
cout << "input the root data: ";
}
cin >> value;
if (value == '#')
{
str = NULL;
return;
}
str = new BinaryTreeNode<T>(value, NULL, NULL);
cout << "input the " << str->data << " leftChild: ";
CreatLeaf(str->leftChild);
cout << "input the " << str->data << " rightChild: ";
CreatLeaf(str->rightChild);
}
template<typename T>
void BinaryTree<T>::Print()
{
this->PrintIoder(this->root);
}
template<typename T>
void BinaryTree<T>::PrintIoder(BinaryTreeNode<T>* str)const
{
if (str != NULL)
{
cout << str->data << " ";
PrintIoder(str->leftChild);
PrintIoder(str->rightChild);
}
else
return;
}
template<typename T>
void BinaryTree<T>::simulate()
{
this->CreatTree();
this->Print();
/*int number = this->NodeOne(this->root);*/
int number = NodeOne();
/*int count = NodeTwo(this->root);*/
int count = NodeTwo();
/*int countLeaf = NodeLeaf(this->root);*/
int countLeaf = NodeLeaf();
/*int height = Height(this->root);*/
int height = Height();
/*int width = FindMaxLine();*/
int width = CountLine();
/*char maxValue = 'a';
this->FindMaxValue(this->root, maxValue);*/
char maxValue = FindMaxValue();
cout << endl;
cout << "the child is one :" << number << endl;
cout << "the child is two :" << count << endl;
cout << "the leaf count is :" << countLeaf << endl;
cout << "the height of the tree is :" << height << endl;
cout << "the tree width is :" << width << endl;
cout << "the maxValue is :" << maxValue << endl;
/*this->ChangLeftRight(this->root);*/
/*this->ChangLeftRight();
this->Print();
cout << endl;*/
this->DeleteLeaf(this->root);
this->Print();
cout << endl;
if (this->isCompleteTree())
{
cout << "该树为完全二叉树" << endl;
}
else
{
cout << "该树不是二叉树" << endl;
}
}
template<typename T>
int BinaryTree<T>::NodeOne(BinaryTreeNode<T>* str)
{
if (str == NULL)
return 0;
if (str->leftChild == NULL&&str->rightChild != NULL)
return NodeOne(str->leftChild) + NodeOne(str->rightChild) + 1;
else if (str->leftChild != NULL&&str->rightChild == NULL)
return NodeOne(str->leftChild) + NodeOne(str->rightChild) + 1;
return NodeOne(str->leftChild) + NodeOne(str->rightChild);
}
template<typename T>
int BinaryTree<T>::NodeOne()
{
//利用深度遍历规则
BinaryTreeNode<T>* str = this->root;
queue<BinaryTreeNode<T>*>node;
int count = 0;
if (str != NULL)
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if ((str->leftChild != NULL&&str->rightChild == NULL) || (str->leftChild == NULL&&str->rightChild != NULL))
count++;
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
return count;
}
template<typename T>
int BinaryTree<T>::NodeTwo(BinaryTreeNode<T>* str)
{
if (str == NULL)
return 0;
if (str->rightChild != NULL&&str->leftChild != NULL)
return NodeTwo(str->leftChild) + NodeTwo(str->rightChild) + 1;
return NodeTwo(str->leftChild) + NodeTwo(str->rightChild);
}
template<typename T>
int BinaryTree<T>::NodeTwo()
{
BinaryTreeNode<T>* str = this->root;
queue<BinaryTreeNode<T>*>node;
int count = 0;
if (str!=NULL)
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if (str->leftChild != NULL&&str->rightChild != NULL)
count++;
if (str->leftChild != NULL)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
return count;
}
template<typename T>
int BinaryTree<T>::NodeLeaf(BinaryTreeNode<T>* str)
{
if (str == NULL)
return 0;
if (str->leftChild == NULL&&str->rightChild == NULL)
return NodeLeaf(str->leftChild) + NodeLeaf(str->rightChild) + 1;
return NodeLeaf(str->leftChild) + NodeLeaf(str->rightChild);
}
template<typename T>
int BinaryTree<T>::NodeLeaf()
{
BinaryTreeNode<T>* str = this->root;
queue<BinaryTreeNode<T>*>node;
int count = 0;
if (str != NULL)
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if (str->leftChild == NULL&&str->rightChild == NULL)
count++;
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
return count;
}
template<typename T>
int BinaryTree<T>::Height(BinaryTreeNode<T>* str)
{
if (str == NULL)
return 0;
int number1 = Height(str->leftChild);
int number2 = Height(str->rightChild);
return number1 > number2 ? number1 + 1 : number2 + 1;
}
template<typename T>
int BinaryTree<T>::Height()
{
if (this->root == NULL)
return 0;
BinaryTreeNode<T>* str = this->root;
int height = 0;
queue<BinaryTreeNode<T>*>node;
node.push(str);
while (!node.empty())
{
height++;
int cur = 0;
int curSize = node.size();
while (cur < curSize)
{
cur++;
str = node.front();
node.pop();
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
}
return height;
}
template<typename T>
void BinaryTree<T>::CountLine(BinaryTreeNode<T>* str,int* ptr,int i)
{
if (str != NULL)
{
//每次递归都将该层的节点数加到相应的数组中去
ptr[i]++;
CountLine(str->leftChild, ptr, i + 1);
CountLine(str->rightChild, ptr, i + 1);
}
}
template<typename T>
int BinaryTree<T>::FindMaxLine()
{
//开辟相应的数组来存储每层的节点数
int height = Height();
int* str = new int[height];
for (int i = 0; i < height; i++)
str[i] = 0;
//获得节点数
CountLine(this->root, str, 0);
int max = 0;
//对数组进行处理,获得最大值
for (int i = 0; i < height; i++)
{
if (max < str[i])
max = str[i];
}
return max;
}
template<typename T>
int BinaryTree<T>::CountLine()
{
//利用非递归的方法求出每层的节点数
BinaryTreeNode<T>* str = this->root;
if (str == NULL)
return 0;
queue<BinaryTreeNode<T>*>node;
node.push(str);
int max = 0;
while (!node.empty())
{
int cur = 0;
int curSize = node.size();
while (cur < curSize)
{
cur++;
str = node.front();
node.pop();
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
if (max < curSize)
max = curSize;
}
return max;
}
template<typename T>
void BinaryTree<T>::FindMaxValue(BinaryTreeNode<T>* str,T& val)
{
if (str == NULL)
return;
if (str->data > val)
val = str->data;
FindMaxValue(str->leftChild, val);
FindMaxValue(str->rightChild, val);
}
template<typename T>
T BinaryTree<T>::FindMaxValue()
{
BinaryTreeNode<T>* str = this->root;
T val = str->data;
queue<BinaryTreeNode<T>*>node;
if (str == NULL)
{
cout << "the tree is empty" << endl;
exit(true);
}
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if (val < str->data)
val = str->data;
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
return val;
}
template<typename T>
void BinaryTree<T>::ChangLeftRight(BinaryTreeNode<T>* str)
{
if (str==NULL)
return;
if (str->leftChild == NULL&&str->rightChild != NULL)
{
str->leftChild = str->rightChild;
str->rightChild = NULL;
}
else if (str->leftChild != NULL&&str->rightChild == NULL)
{
str->rightChild = str->leftChild;
str->leftChild = NULL;
}
else
{
BinaryTreeNode<T>* p = str->leftChild;
str->leftChild = str->rightChild;
str->rightChild = p;
}
ChangLeftRight(str->leftChild);
ChangLeftRight(str->rightChild);
}
template<typename T>
void BinaryTree<T>::ChangLeftRight()
{
BinaryTreeNode<T>* str = this->root;
queue<BinaryTreeNode<T>*>node;
if (str == NULL)
{
cout << "the tree is empty" << endl;
exit(true);
}
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if (str->leftChild != NULL&&str->rightChild == NULL)
{
str->rightChild = str->leftChild;
str->leftChild = NULL;
}
else if (str->leftChild == NULL&&str->rightChild != NULL)
{
str->leftChild = str->rightChild;
str->rightChild = NULL;
}
else{
BinaryTreeNode<T>* p = str->leftChild;
str->leftChild = str->rightChild;
str->rightChild = p;
}
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
}
}
template<typename T>
void BinaryTree<T>::DeleteLeaf(BinaryTreeNode<T>* &str)
{
if (str == NULL)
return;
if (str->leftChild == NULL&&str->rightChild == NULL)
{
delete str;
str = NULL;
return;
}
DeleteLeaf(str->leftChild);
DeleteLeaf(str->rightChild);
}
template<typename T>
bool BinaryTree<T>::isCompleteTree()const
{
bool flag = true;
BinaryTreeNode<T>* str = this->root;
if (str == NULL)
return true;
queue<BinaryTreeNode<T>*>node;
node.push(str);
while (!node.empty())
{
str = node.front();
node.pop();
if (flag && (str->leftChild || str->rightChild))
return false;
if (str->leftChild)
node.push(str->leftChild);
if (str->rightChild)
node.push(str->rightChild);
if (str->leftChild == NULL&&str->rightChild)
return false;
if (str->rightChild == NULL)
flag = false;
}
return true;
}
template<typename T>
int BinaryTree<T>::NodeNumber()const
{
BinaryTreeNode<T>* str = this->root;
if (str == NULL)
{
cout << "the tree is empty" << endl;
return 0;
}
queue<BinaryTreeNode<T>*>node;
node.push(str);
int count = 1;
while (!node.empty())
{
str = node.front();
node.pop();
if (str->leftChild)
{
node.push(str->leftChild);
count++;
}
if (str->rightChild)
{
node.push(str->rightChild);
count++;
}
}
return count;
}
#endif
//主函数
#include"BinaryTree.h"
int main(int argc, char argv[])
{
BinaryTree<char>tree;
tree.simulate();
return 0;
}