关闭

二叉树中包括高度,深度,节点数,宽度,最大值等的递归和非递归方法

标签: 二叉树递归算法遍历
166人阅读 评论(0) 收藏 举报
分类:
//头文件
//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;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20349次
    • 积分:912
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:0篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论