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

原创 2015年11月19日 16:46:16
//头文件
//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;
}

求二叉树节点数 -- 采用递归和非递归方法

/*求二叉树节点数 -- 采用递归和非递归方法(本例非递归采用先序遍历) 经调试可运行源码及分析如下: ***/ #include #include #include using std::cou...
  • y396397735
  • y396397735
  • 2016年04月14日 05:26
  • 1282

递归遍历 二叉树 求高度 和 节点数 和 叶子节点数

递归遍历 二叉树 求高度 和 节点数 和 叶子节点数
  • u013514722
  • u013514722
  • 2014年11月07日 13:59
  • 1617

二叉树非递归遍历、层次遍历、高度、节点数

// 参考大神所写 http://blog.csdn.net/hackbuteer1/article/details/6583988 #include #include #include #i...
  • damotiansheng
  • damotiansheng
  • 2016年05月24日 20:32
  • 1489

二叉树深度与高度的区别

http://blog.csdn.net/fanpei_moukoy/article/details/23828603
  • mantantan
  • mantantan
  • 2016年11月02日 10:23
  • 3475

求二叉树的深度递归与非递归版

当只有一个节点时,二叉树的深度为1,这与求二叉树的高度略微有点不同。 #include using namespace std; struct TreeNode { int val; ...
  • zhanglei0107
  • zhanglei0107
  • 2013年09月09日 11:01
  • 6410

查找树ADT--二叉查找树

二叉树的一个重要应用是它们在查找中的使用。   二叉查找树的性质:对于树中的每个节点X,它的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。这意味着该树所有的元素可以用某种一致的...
  • tanga842428
  • tanga842428
  • 2016年09月05日 18:20
  • 588

每周数据结构【3】:设计一个非递归的算法求二叉树高度

思路:用到非递归的思想,毫无疑问就是使用 树的层次遍历方法来做 采用层次遍历算法,设置变量level记录当前的节点所在存数。设置变量level指向当前节点的最右边,每次遍历之后就和level进行比较...
  • u014174955
  • u014174955
  • 2016年03月17日 12:22
  • 1502

笔记-AVL树

空谈误国,实干兴邦! 近日事务繁多,自己也有懈怠。
  • qq_34267645
  • qq_34267645
  • 2016年04月15日 20:43
  • 291

数据结构课程设计~二叉树的应用(二叉树)

/*     二叉树的应用(二叉树)          [问题描述]         编程实现二叉树的建立,先序、中序、后序(递归和非递归方法)、层序遍历,二叉树的高度、繁茂度,     交...
  • m0_37338590
  • m0_37338590
  • 2017年03月07日 20:58
  • 301

二叉树中节点的最大距离(树的最长路径)——递归解法

问题描述: 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的, 我们姑且定义"距离"为两节点之间边的个数。 写一个程序, 求一棵二叉树中相距最远的两个节点之间的距离。...
  • hgqqtql
  • hgqqtql
  • 2014年10月05日 03:33
  • 4324
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:二叉树中包括高度,深度,节点数,宽度,最大值等的递归和非递归方法
举报原因:
原因补充:

(最多只允许输入30个字)