面试题8-二叉树的下一个节点(C++从构建树、打印树、销毁树等code)

完整版本:从构建树,到打印树一整套code

#include<iostream>

struct BinaryTreeNode
{
	int n_mValue;
	BinaryTreeNode* n_pLeft;
	BinaryTreeNode* n_pRight;
	BinaryTreeNode* n_parent;
	BinaryTreeNode(int value) :
		n_mValue(value),n_parent(nullptr),
		n_pLeft(nullptr), n_pRight(nullptr) {}
};
class BinaryTree
{
	BinaryTreeNode* root;
public:
	//创建二叉树
	void Creat_Tree(int parent, int left, int right);
	//前序遍历
	void preOrder();
	//中序遍历
	void inOrder();
	//后续遍历
	void posOrder();
	//得到中序的下一个节点
	BinaryTreeNode* get_InNext(int value);
	//析构函数
	~BinaryTree() { clear(); }
	//摧毁树
	void clear();
private:
	void _preOrder(BinaryTreeNode* _root);
	void _inOrder(BinaryTreeNode* _root);
	void _posOrder(BinaryTreeNode* _root);
	void _clear(BinaryTreeNode* root);
	//找某个节点
	BinaryTreeNode* find_Node(int value);
	BinaryTreeNode* _find_Node(BinaryTreeNode* node, int value);
	BinaryTreeNode* _get_InNext(BinaryTreeNode* pNode);
}; 
void BinaryTree::_clear(BinaryTreeNode* root)
{
	if (root)
	{
		_clear(root->n_pLeft);
		_clear(root->n_pLeft);
		delete root;
	}
}
void BinaryTree::clear()
{
	_clear(root);
}
void BinaryTree::posOrder()
{
	_posOrder(root);
}
void BinaryTree::inOrder()
{
	_inOrder(root);
}
void BinaryTree::preOrder()
{
	_preOrder(root);
}
void BinaryTree::_posOrder(BinaryTreeNode* _root)
{
	if (_root)
	{
		if(_root->n_pLeft)
		_posOrder(_root->n_pLeft);
		if(_root->n_pRight)
		_posOrder(_root->n_pRight);
		std::cout << _root->n_mValue << " ";
	}
}
void BinaryTree::_inOrder(BinaryTreeNode* _root)
{
	if (_root)
	{
		if (_root->n_pLeft)
		_inOrder(_root->n_pLeft);
		std::cout << _root->n_mValue << " ";
		if (_root->n_pRight)
		_inOrder(_root->n_pRight);
	}
}
void BinaryTree::_preOrder(BinaryTreeNode* _root)
{
	if (_root)
	{
		std::cout << _root->n_mValue << " ";
		if (_root->n_pLeft)
		_preOrder(_root->n_pLeft);
		if (_root->n_pRight)
		_preOrder(_root->n_pRight);
	}
}
void BinaryTree::Creat_Tree(int parent, int left, int right)
{
	if (root)
	{
		
		BinaryTreeNode* p_parent = find_Node(parent);
		if (p_parent)//判断父节点是否在树中,不在则抛出异常
		{
			p_parent->n_pLeft = new BinaryTreeNode(left);
			p_parent->n_pRight = new BinaryTreeNode(right);
		}
		else
		{
			throw std::exception("Invalid Input!");
		}
	}
	else
	{
		//如果树为空,先建立根节点
		root = new BinaryTreeNode(parent);
		BinaryTreeNode* p_left = new BinaryTreeNode(left);
		BinaryTreeNode* p_right = new BinaryTreeNode(right);
		root->n_pLeft = p_left;
		root->n_pRight = p_right;
	}
}
BinaryTreeNode* BinaryTree::find_Node(int value)
{
	return _find_Node(root, value);
}
BinaryTreeNode* BinaryTree::_find_Node(BinaryTreeNode* node, int value)
{
	if (node)
	{
		if (node->n_mValue == value)return node;
		BinaryTreeNode* tempNode = _find_Node(node->n_pLeft, value);
		if (tempNode)return tempNode;//如果没有作判断,如果在左子树为空时,直接返回空并结束递归
		return _find_Node(node->n_pRight, value);
	}
	return nullptr;
}
BinaryTreeNode* BinaryTree::get_InNext(int value)
{
	BinaryTreeNode* pNode = find_Node(value);
	return _get_InNext(pNode);
}
BinaryTreeNode* BinaryTree::_get_InNext(BinaryTreeNode* pNode)
{
	if (pNode == nullptr)return nullptr;
	BinaryTreeNode* pNext = nullptr; 
	if (pNode->n_pRight != nullptr)
	{
		//选定节点的右节点不为空,则该节点的下一个节点为右子树的左子树的最后一个节点
		BinaryTreeNode* p_right = pNode->n_pRight;
		while (p_right->n_pLeft != nullptr)
			p_right = p_right->n_pLeft;
		pNext = p_right;
	}
	else if (pNode->n_parent != nullptr)
	{
		//选定节点的父节点不为空,如果该节点为左子节点,下一个节点为该节点的父节点;
		//如果该节点为右子节点,则其父节点的父节点为其下一个节点
		BinaryTreeNode* pCurrent = pNode;
		BinaryTreeNode* pParent = pNode->n_parent;
		while (pParent != nullptr && pCurrent == pParent->n_pRight)
		{
			pCurrent = pParent;
			pParent = pParent->n_parent;
		}
		pNext = pParent;
	}
	return pNext;
}
int main()
{
	BinaryTree B;
	B.Creat_Tree(8, 6, 10);
	B.Creat_Tree(6, 5, 7);
	B.Creat_Tree(10, 9, 11);
	B.preOrder();
	std::cout << std::endl;
	B.inOrder();
	std::cout << std::endl;
	B.posOrder();
	std::cout << std::endl;
	BinaryTreeNode*next=B.get_InNext(10);
	std::cout << next->n_mValue << std::endl;
	std::cin.get();
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值