二叉树面试题-镜像与判断是否为完全二叉树

二叉树部分面试题

关于二叉树的一些面试题在下面的文章已经写过了,

在这里做一些补充。

九、求二叉树的镜像

二叉树的镜像树就是把一个节点下的左右孩子交换,例如:

这样与层序遍历还有些相似,实现如下:

递归

//求二叉树的镜像
	PNode _MirrorBinTree1(PNode pRoot)
	{
		if (pRoot == NULL)
			return 0;
		swap(pRoot->_left, pRoot->_right);
		_MirrorBinTree1(pRoot->_left);
		_MirrorBinTree1(pRoot->_right);
		return pRoot;
	}

非递归

//求二叉树的镜像
	PNode _MirrorBinTree2(PNode pRoot)
	{
		if (pRoot == NULL)
			return 0;
		queue<PNode> q;
		q.push(pRoot);
		while (!q.empty())
		{
			PNode front = q.front();
			swap(front->_left, front->_right);
			q.pop();

			if (front->_left)
				q.push(front->_left);
			if (front->_right)
				q.push(front->_right);
		}
	}

十、判断二叉树是否为完全二叉树

完全二叉树的概念文章开始已经讲过。二叉树可分为空树,只有一个节点,多个节点。而多个节点可分为以下方面:

1、左右子树均存在

2、只有左,没有右

3、只有右,没有左(false)

4、没有左右子树

我们利用队列实现,如下:

代码如下:

bool _CompleteBinTree(PNode pRoot)
	{
		if (pRoot == NULL)
			return 1;
		if (pRoot->_left == NULL && pRoot->_right == NULL)
			return 0;

		queue<PNode> q;
		q.push(pRoot);
		bool flag = false;
		while (!q.empty())
		{
			PNode pCur = q.front();
			q.pop();
			if (pCur->_left == NULL || pCur->_right == NULL)
			{
				if (pCur->_left == NULL&&pCur->_right != NULL)
				{
					q.push(pCur->_left);
					flag = true;
				}
				else if (pCur->_right == NULL&&pCur->_left != NULL)
				{
					flag = false;
				}
				else
					flag = true;
			}
			else
			{
				q.push(pCur->_left);
				q.push(pCur->_right);
			}
		}
		return flag;
	}

测试:

template<class T>
struct TreeNode
{
	T _data;
	TreeNode *_left;
	TreeNode *_right;
	TreeNode(const T& data)
		:_data(data)
		, _left(NULL)
		, _right(NULL)
	{}
};

template<class T>
class BinTree
{
	typedef TreeNode<T> Node;
	typedef TreeNode<T> *PNode;
public:
	BinTree()
		: _pRoot(NULL)
	{}

	BinTree(const T* array, size_t size, const T& invalid)
	{
		size_t index = 0;
		_pRoot = _CreateBinTree(array, size, index, invalid);
	}

	BinTree(const BinTree& bt)
	{
		_pRoot = _CopyBinTree(bt._pRoot);
	}

	BinTree& operator=(const BinTree& bt)
	{
		if (this == bt)
			return;
		_DestroyBinTree(_pRoot);
		_pRoot = new Node(bt->_data);
		_pRoot->_left = bt->_left;
		_pRoot->_right = bt->_right;
	}

	~BinTree()
	{
		_DestroyBinTree(_pRoot);
	}

	void PreOrder()
	{
		_PreOrder1(_pRoot);
		cout << endl;
	}

	PNode MirrorBinTree1()
	{

		return _MirrorBinTree1(_pRoot);
	}
	PNode MirrorBinTree2()
	{

		return _MirrorBinTree2(_pRoot);
	}
	bool CompleteBinTree()
	{
		return _CompleteBinTree(_pRoot);
	}

private:
	//求二叉树的镜像
	PNode _MirrorBinTree1(PNode pRoot)
	{
		if (pRoot == NULL)
			return 0;
		swap(pRoot->_left, pRoot->_right);
		_MirrorBinTree1(pRoot->_left);
		_MirrorBinTree1(pRoot->_right);
		return pRoot;
	}
	//求二叉树的镜像
	PNode _MirrorBinTree2(PNode pRoot)
	{
		if (pRoot == NULL)
			return 0;
		queue<PNode> q;
		q.push(pRoot);
		while (!q.empty())
		{
			PNode front = q.front();
			swap(front->_left, front->_right);
			q.pop();

			if (front->_left)
				q.push(front->_left);
			if (front->_right)
				q.push(front->_right);
		}
	}
	//判断完全二叉树
	bool _CompleteBinTree(PNode pRoot)
	{
		if (pRoot == NULL)
			return 1;
		if (pRoot->_left == NULL && pRoot->_right == NULL)
			return 0;

		queue<PNode> q;
		q.push(pRoot);
		bool flag = false;
		while (!q.empty())
		{
			PNode pCur = q.front();
			q.pop();
			if (pCur->_left == NULL || pCur->_right == NULL)
			{
				if (pCur->_left == NULL&&pCur->_right != NULL)
				{
					q.push(pCur->_left);
					flag = true;
				}
				else if (pCur->_right == NULL&&pCur->_left != NULL)
				{
					flag = false;
				}
				else
					flag = true;
			}
			else
			{
				q.push(pCur->_left);
				q.push(pCur->_right);
			}
		}
		return flag;
	}
private:
		PNode _pRoot;
};


测试:

int main()
{
	//完全二叉树
	char array1[] = "abc##d##ef##g";
	BinTree<char> bt1(array1,strlen(array1),'#');

	//不完全二叉树
	char array2[] = "abc###def##g";
	BinTree<char> bt2(array2, strlen(array2), '#');

	bt1.PreOrder();
	bt1.MirrorBinTree1();
	bt1.MirrorBinTree2();
	bt1.PreOrder();

	cout << bt1.CompleteBinTree() << endl;
	cout << bt2.CompleteBinTree() << endl;
	system("pause");
	return 0;
}


两次镜像应该返回原样,测试结果:




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值