C++二叉树实现

1.0 你怎么对二叉树进行遍历,你就可以使用这种遍历方式来创建二叉树。
	因此二叉树的创建方式有很多种,我选择的是层次创建(与其相对应的是层次遍历,
	也叫广度优先遍历)2.0 二叉树的销毁也可以使用其特定的遍历方式进行销毁。
3.0 因为层次遍历的过程很适合队列这种结构,所以可以使用queue来实现该遍历过程。

代码:

/*
	(1)根据遍历的方式创建二叉树,你打算怎么遍历就怎么创建。	
	(2)使用堆栈存储二叉树,并使用先序遍历。
	 (3) 在插入的时候你怎么分插在左节点还是右节点?不分的话,如何插入?
	 (4) 利用数组常见二叉树,用标识符分左右
*/

#pragma once
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
// 二叉树结点 
template <typename T>
class BinTreeNode {
public:
	T data;
	BinTreeNode<T>* left;
	BinTreeNode<T>* right;
	BinTreeNode(T data_) 
		:data{data_},left{nullptr},right{nullptr}
	{}
};

template <typename T>
class BinTree
{
	typedef BinTreeNode<T> node;
private:
protected:
	node* root;
	void PreorderTraversal_(node *root);
	void PreoderTraversalByStack_(node* root);
	void MiddleTraversal_(node* root);
	void MiddleTraversalByStack_(node* root);
	void PostTraversal_(node* root);
	void PostTraversalByStack_(node* root);

	void NodeSize_(node* rootTemp, size_t& size);
	node* Find_(node* root, const T& x);
	size_t LeafNodeSize_(node*root);
	size_t Height_(node* root);
	size_t NodeSizeKth_(node* root, size_t k);

public:
	BinTree(T* dataArr_, size_t dataArrLength, const T& nullMark, size_t index = 0);
	~BinTree();
	/// 错误的地方,这里没有传递index 的引用,卧槽。
	// 使用数组初始化二叉树:
	//创建一棵二叉树------
	node* CreateBinTree(T* dataArr_, size_t dataArrLength, const T& nullMark, size_t& index);
	// 传过去一个root 是为了不修改 原本对象的root;
	// 在这里调用根,来隐藏根节点。
	void PreoderTraversal(); 
	void PreoderTraversalByStack();
	void MiddleTraversal()
	{
		MiddleTraversal_(root);
	}
	void MiddleTraversalByStack()
	{
		MiddleTraversalByStack_(root);
	}
	void PostTraversal()
	{
		PostTraversal_(root);
	}
	void PostTraversalByStack()
	{
		PostTraversalByStack_(root);
	}
	//层序遍历
	void FloorOrder();
	// 使用后续遍历,析构树
	void DestroyTree(node* root);
	// 树的节点个数
	size_t NodeSize();
	//求叶子节点的个数
	size_t LeafNodesize();
	//判断二叉树是否为完全二叉树
	bool isCompleteTree();
	//查找一个节点是否在一棵二叉树中
	node* Find(const T& x);
	// 求二叉树的高度:
	size_t Height();
	// 求第k层的节点个数:
	size_t NodeSizeKth(size_t k);
	// 寻找路径:
	void FindPath();
};
// 构造
template<typename T>
BinTree<T>::BinTree(T * dataArr_, size_t dataArrLength, const T & nullMark, size_t index)
{
	root = CreateBinTree(dataArr_, dataArrLength, nullMark, index);
}
// 析构
template<typename T>
BinTree<T>::~BinTree()
{
	DestroyTree(root);
}

template<typename T>
BinTreeNode<T>* BinTree<T>::CreateBinTree(T * dataArr_, size_t dataArrLength, const T & nullMark, size_t & index)
{
	BinTreeNode<T>* root = nullptr;
	if (dataArr_[index] != nullMark)
	{
		root = new BinTreeNode<T>(dataArr_[index]);
		root->left = CreateBinTree(dataArr_, dataArrLength, nullMark, ++index);
		root->right = CreateBinTree(dataArr_, dataArrLength, nullMark, ++index);
	}
	return root;
}

template<typename T>
void BinTree<T>::DestroyTree(node * root)
{
	if (root == nullptr)
		return;
	DestroyTree(root->left);
	DestroyTree(root->right);
	delete root;
}

// 先序-递归
template<typename T>
void BinTree<T>::PreoderTraversal()
{
	PreorderTraversal_(root);
}

template<typename T>
void BinTree<T>::PreorderTraversal_(node * root)
{
	if (root == nullptr)
		return;
	std::cout << root->data << "  ";
	PreorderTraversal_(root->left);
	PreorderTraversal_(root->right);
}
// 先序-堆栈
template<typename T>
void BinTree<T>::PreoderTraversalByStack()
{
	PreoderTraversalByStack_(root);
}

template<typename T>
void BinTree<T>::MiddleTraversalByStack_(node * root)
{
	node* currentNode = root;
	stack<node*>s;
	while (currentNode || !s.empty())
	{
		while (currentNode)
		{
			s.push(currentNode);
			currentNode = currentNode->left;
		}
		node* top = s.top();
		cout << top->data << "  ";
		s.pop();

		currentNode = top->right;
	}
	cout << endl;
}

template<typename T>
void BinTree<T>::MiddleTraversal_(node * root)
{
	if (root == nullptr)
		return;
	MiddleTraversal_(root->left);
	cout << root->data << "  ";
	MiddleTraversal_(root->right);
}

template<typename T>
void BinTree<T>::PostTraversal_(node * root)
{
	if (root == nullptr)
		return;
	PostTraversal_(root->left);
	PostTraversal_(root->right);
	cout << root->data << "  ";
}

template<typename T>
void BinTree<T>::PostTraversalByStack_(node * root)
{
	node* currentNode = root;
	node*previous = nullptr;
	stack<node*>s;
	while (currentNode || !s.empty())
	{
		while (currentNode)
		{
			s.push(currentNode);
			currentNode = currentNode->left;
		}
		node* top = s.top();
		if (top->right == NULL || top->right == previous)
		{
			cout << top->data << "  ";
			s.pop();
			previous = top;
		}
		else
		{
			currentNode = top->right;
		}
	}
	cout << endl;
}

template<typename T>
void BinTree<T>::FloorOrder()
{
	queue<node *>q;
	if (root)
		q.push(root);
	while (!q.empty())
	{
		node* front = q.front();
		cout << front->data << "  ";
		q.pop();
		if (front->left)
			q.push(front->left);
		if (front->right)
			q.push(front->right);
	}
	cout << endl;
}

template<typename T>
void BinTree<T>::PreoderTraversalByStack_(node * root)
{
	node* currentNode = root;
	std::stack<node*>s;
	while (currentNode || !s.empty())
	{
		while (currentNode)
		{
			std::cout << currentNode->data << " ";
			s.push(currentNode);
			currentNode = currentNode->left;
		}
		node* top = s.top();
		s.pop();
		//子问题
		currentNode = top->right;
	}
	std::cout << std::endl;
}

template<typename T>
size_t BinTree<T>::NodeSize()
{
	size_t size = 0;
	NodeSize_(root, size);
	return size;
}

template<typename T>
void BinTree<T>::NodeSize_(node* rootTemp, size_t& size)
{
	if (rootTemp == nullptr)
		return;
	NodeSize_(rootTemp->left, size);
	++size;
	NodeSize_(rootTemp->right, size);
}

template<typename T>
size_t BinTree<T>::LeafNodesize()
{
	return LeafNodeSize_(root);
}
template<typename T>
size_t BinTree<T>::LeafNodeSize_(node * root)
{
	// 二叉树为空的时候
	if (root == NULL)return 0;
	// 二叉树只有一个节点的时候
	if (root->left == NULL && root->right == NULL)
		return 1;
	// 叶子节点 = 左子树叶子节点 + 右子树叶子节点
	return LeafNodeSize_(root->left) + LeafNodeSize_(root->right);
}

template<typename T>
inline bool BinTree<T>::isCompleteTree()
{
	queue<node*>q;
	if (root)
		q.push(root);
	bool flag = true;
	while (!q.empty())
	{
		node* front = q.front();
		q.pop();
		if (front->left)
		{
			if (flag == false)
				return false;
			q.push(front->left);
		}
		else
			flag = false;
		
		if (front->right)
		{
			if (flag == false)
				return false;
			q.push(front->right);
		}
		else
			flag = false;
	}
	return true;
}

template<typename T>
BinTreeNode<T>* BinTree<T>::Find(const T & x)
{
	return Find_(root, x);
}

template<typename T>
size_t BinTree<T>::Height()
{
	return Height_(root);
}

template<typename T>
size_t BinTree<T>::Height_(node* root)
{
	//二叉树为空的时候,高度为0
	if (root == nullptr) return 0;
	size_t leftHeight = Height_(root->left);
	size_t rightHeight = Height_(root->right);
	//二叉树非空时,高度为左子树和右子树中较高的一个
	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

template<typename T>
size_t BinTree<T>::NodeSizeKth(size_t k)
{
	return NodeSizeKth_(root, k);
}

template<typename T>
size_t BinTree<T>::NodeSizeKth_(node* root,size_t k)
{
	//空树返回0
	if (root == nullptr) return 0;
	//第一层只有一个节点
	if (k == 1) return 1;
	//注意这里为什么是k-1?  如果你需要求第二层的节点个数,则需要用第一层的根节点访问他的左子树和右子树的第一层的个数
	return NodeSizeKth_(root->left, k - 1) + NodeSizeKth_(root->right, k - 1);
}

template<typename T>
BinTreeNode<T>* BinTree<T>::Find_(node* root, const T & x)
{
	if (root == nullptr)
		return nullptr;
	if (root->data == x)
		return root;
	node* ret1 = Find_(root->left, x);
	if (ret1)return ret1;
	node* ret2 = Find_(root->data, x);
	if (ret2)return ret2;

	return nullptr;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值