《劍指offer》:[59]對稱的二叉樹

塵虛緣_KY發表於2016-06-28
題目;請實現一個函式,用來判斷一棵二叉樹是不是對稱的。如果一顆二叉樹和它的映象一樣,那麼它是對稱的。

例如,下面二棵樹圖(1)就是對稱的二叉樹,而圖(2)(3)就不是的。


分析:我們知道樹的遍歷有三種方式:前,中,後。顧名思義,對稱就是左邊的和右邊的相等,中間的自己等於自己。所以我們自己可以定義一種對稱遍歷演算法,例如前序遍歷中的前,左,右。對稱演算法就是:前,右,左。剛好對稱比較。當然了其他的中和後序遍歷也行,我們也可以定義與其對應的對稱演算法。但是其中為了避免出現樹(3)中的遍歷出來的資料一樣,造成誤判,我們需要對葉子結點加上標識,如空節點需要設定為NULL。而不能只是比較遍歷後的資料。
具體是實現程式碼如下:
#include <iostream>
using namespace std;
struct BinaryTree
{
	int data;
	BinaryTree *pLeft;
	BinaryTree *pRight;
};
BinaryTree *pRoot1=NULL;
BinaryTree *pRoot2=NULL;
BinaryTree *pRoot3=NULL;
void CreateTree(BinaryTree * &root)
{
	int data;
	cin>>data;
	if(0==data)
		root=NULL;
	else
	{
		root=new BinaryTree;
		root->data=data;
		//前序遍歷構建二叉樹;
		CreateTree(root->pLeft);
		CreateTree(root->pRight);
	}
}
bool IsSymmetricalHelp(BinaryTree *root1,BinaryTree *root2)
{
	if(root1==NULL && root2==NULL)
		return true;
	if(root1==NULL || root2==NULL)//把null也算上,很重要,防止資料一樣的特殊情況;
		return false;
	if(root1->data!=root2->data)
		return false;
	return IsSymmetricalHelp(root1->pLeft,root2->pRight) 
		&& IsSymmetricalHelp(root1->pRight,root2->pLeft);
}
bool IsSymmetrical(BinaryTree *root)
{
	return IsSymmetricalHelp(root,root);
}
void PreOrder(BinaryTree *root)
{
	if(root)
	{
		cout<<root->data<<" ";
		PreOrder(root->pLeft);
		PreOrder(root->pRight);
	}
}
void UntiPreOrder(BinaryTree *root)
{
	if(root)
	{
		cout<<root->data<<" ";
		PreOrder(root->pRight);
		PreOrder(root->pLeft);
	}
}
int main()
{
	bool result=false;
	CreateTree(pRoot1);
	cout<<"樹1的--前序遍歷:";
	PreOrder(pRoot1);
	cout<<endl;
	cout<<"樹1的反前序遍歷:";
	UntiPreOrder(pRoot1);
	result=IsSymmetrical(pRoot1);
	if(result)
		cout<<endl<<"該樹是對稱樹!"<<endl;
	else
		cout<<"該樹不是對稱樹!"<<endl;
	cout<<endl;


	CreateTree(pRoot2);//樹3雖然遍歷一樣,但是不是對成樹!
	cout<<"樹2的--前序遍歷:";
	PreOrder(pRoot2);
	cout<<endl;
	cout<<"樹2的反前序遍歷:";
	UntiPreOrder(pRoot2);
	cout<<endl;
	result=IsSymmetrical(pRoot2);
	if(result)
		cout<<"該樹是對稱樹!"<<endl;
	else
		cout<<"該樹不是對稱樹!"<<endl;
	cout<<endl;
	system("pause");
	return 0;
}

執行結果如下;



相關文章