二叉树镜像判断

一、前言

《二叉树的镜像》在验证二叉树是互为镜像时,给出了三种方法,本文对这三种方法进行说明

二、题目

判断两颗二叉树是否互为镜像。

三、思路

三种解决方法:

方法一,将其中一颗二叉树转为镜像,并与另外一棵树进行比较判断各节点值是否相等

方法二,互为镜像的两个二叉树,每层数据顺序相反,逐层判断即可,需要注意结点为空的情况。前面文章中《从上往下打印二叉树》给出了获得逐层获得树数据方法。

方法三:递归实现——树1左结点和树2右结点判断;树1右结点和树2左结点判断。

三种方法特点:

方法一:在《二叉树的镜像》基础上可以得到镜像,比较两个镜像树结点是否相等,理解了《二叉树的镜像》,这种方法也就很好理解

方法二:互为镜像的二叉树,每层数据顺序相反,直接判断即可,易于理解但是获得每层数据和比较相等麻烦些。

方法三种:思路相对抽象,编码简单。

四、编码实现

//==========================================================================
/**
* @file : MirrorOfBinaryTreeJudge.h
* @purpose : 输入两棵二叉树A和B,判断B是不是A的子结构。
*
* 有三种解决方案
*/
//==========================================================================

#pragma once
#include "MirrorOfBinaryTree.h"

// 判断二个二叉树是否相等(所有结点相等)
template<class T>
bool BinaryTreeEqual(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB)
{
	if (pRootA == nullptr && pRootB == nullptr)
	{
		return true;
	}
	else if (pRootA != nullptr && pRootB != nullptr)
	{
		return BinaryTreeEqual(pRootA->m_pLeft, pRootB->m_pLeft) && BinaryTreeEqual(pRootA->m_pRight, pRootB->m_pRight);
	}
	else
	{
		return false;
	}
}

////////////////////// 方法一 ///////////////////////////////////////
// 方法一
// 思路:先将其中一个树转为镜像再与另外一棵树进行比较,相等则互为镜像
template<class T>
bool MirrorOfBinaryTreeJudge_Solution1(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB)
{
	// 约定两个空树不互为镜像
    if (pRootA == nullptr || pRootB == nullptr)
    {
        return false;
    }

	MirrorOfBinaryTree(pRootA);	// 将pRootA,转为镜像,若pRootA和pRootB结点值相等则pRootA和pRootB互为镜像
	bool result = BinaryTreeEqual(pRootA, pRootB);
	MirrorOfBinaryTree(pRootA);	// 有前面将pRootA转为了镜像,此处需要回复他的镜像
	
	return result;
}

////////////////////// 方法二 ///////////////////////////////////////
// 方法二
// 思路:互为镜像的特定是,每一层数据顺序相反。需要考虑到结点为空的情况。
template<class T>
bool MirrorOfBinaryTreeJudge_Solution2(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB)
{
	// 约定两个空树不互为镜像
	if (pRootA == nullptr || pRootB == nullptr)
	{
		return false;
	}

	map<int, vector<BinaryTreeNode<T>*>> dataA;		//记录的是每行节点值
	GetTreesInLines(pRootA, dataA);

	map<int, vector<BinaryTreeNode<T>*>> dataB; //记录的是每行节点值
	GetTreesInLines(pRootB, dataB);

	// 判断两个二叉树是否互为镜像
	bool result = true;
	if (dataA.size() == dataB.size())
	{
		auto itA = dataA.begin();
		auto itB = dataB.begin();
		for (size_t i = 0; i < dataA.size(); i++, itA++, itB++)
		{
			if (itA->second.size() == itB->second.size())
			{
				size_t len = itA->second.size();
				for (size_t j = 0; j < len; j++)
				{
					size_t tailIndex = len - 1 - j;
					if (itA->second[j] == nullptr && itB->second[tailIndex] == nullptr)
					{
						continue;
					}
					else if (itA->second[j] != nullptr && itB->second[tailIndex] != nullptr)
					{
						if (itA->second[j]->m_nValue != itB->second[tailIndex]->m_nValue)
						{
							result = false;
							break;
						}
					}
					else
					{
						result = false;
						break;
					}
				}

				if (!result)
				{
					break;
				}
			}
			else
			{
				result = false;
			}
		}
	}
	else
	{
		result = false;
	}

	return result;
}

////////////////////// 方法三 ///////////////////////////////////////
// 方法三
// 思路:镜像树特点,左子树为镜像树右子树;右子树为镜像树左子树

template<class T>
bool MirrorOfBinaryTreeJudge_Solution3_Operate(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB);

template<class T>
bool MirrorOfBinaryTreeJudge_Solution3(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB)
{
	// 约定两个空树不互为镜像
	if (pRootA == nullptr || pRootB == nullptr)
	{
		return false;
	}

	return MirrorOfBinaryTreeJudge_Solution3_Operate(pRootA, pRootB);
}

template<class T>
bool MirrorOfBinaryTreeJudge_Solution3_Operate(BinaryTreeNode<T>* pRootA, BinaryTreeNode<T>* pRootB)
{
	// 约定两个空树不互为镜像
	if (pRootA == nullptr && pRootB == nullptr)
	{
		return true;
	}

	if (pRootA == nullptr || pRootB == nullptr)
	{
		return false;
	}

	if (pRootA->m_nValue != pRootB->m_nValue)
	{
		return false;
	}

	return MirrorOfBinaryTreeJudge_Solution3_Operate(pRootA->m_pLeft, pRootB->m_pRight) 
		&& MirrorOfBinaryTreeJudge_Solution3_Operate(pRootA->m_pRight, pRootB->m_pLeft);
}

// 测试用例见 《二叉树的镜像》

二叉树的镜像https://blog.csdn.net/nie2314550441/article/details/106183227

猜你喜欢

转载自blog.csdn.net/nie2314550441/article/details/106189949
今日推荐