二叉樹鏡像使用遞歸法和循環法

該題目參考自<<劍指Offer>>第19題目

求一顆樹的鏡像的過程:我們先前序遍歷這顆樹的每個結點,如果遍歷到的結點有子結點,就交換它的兩個子結點。當交換完所有非葉子結點的左右子節點之後,就得到了樹的鏡像。


a圖中爲一個二叉樹,遍歷此二叉樹,先交換根節點8的左右子樹,如圖中紅色區域。


如圖c,接着遍歷到10結點,交換其左右子樹。如圖中紅色區域。


如圖e,遍歷到結點6,交換其左右子樹。如圖中紅色區域。

遞歸法求二叉樹鏡像

<pre name="code" class="html">void MirrorRecursively(binarytree * head)
{
	if(head==NULL)//二叉樹爲空樹
		return;
	if(head->lchild==NULL&&head->rchild==NULL)//當左右子結點都爲空
		return;
	
	binarytree * temp=head->lchild;//語句段1
	head->lchild=head->rchild;//
	head->rchild=temp;//

	if(head->lchild)//語句段2
		MirrorRecursively(head->lchild);//
	if(head->rchild)//
		MirrorRecursively(head->rchild);//	

	
}



上面程序中語句段1與語句段2是可以交換的。既可以先交換當前結點的左右子樹,再調用遞歸函數處理其左右子結點。也可以先調用遞歸函數處理其左右子結點,然後再交換其左右子樹。兩者的區別是處理結點的順序有差異,但是鏡像的結果是一致的。

循環法求二叉樹鏡像,需要使用到STL隊列。

void MirrorLoopLy(binarytree *head)
{
	if(head==NULL)
		return;
	queue<binarytree *> que;
	que.push(head);
	while(!que.empty())
	{
		binarytree * node=que.front();
		que.pop();
		binarytree * temp=node->lchild;
		node->lchild=node->rchild;
		node->rchild=temp;
		if(node->lchild)
			que.push(node->lchild);
		if(node->rchild)
			que.push(node->rchild);
	}
	
}
上面程序中,語句段1與語句2的位置可以交換。既可以先交換結點的左右子樹,再把其左右子結點加入隊列。也可以先把其左右子樹加入隊列,再交換其左右子樹。兩者的區別是結點被處理的先後順序有差異,鏡像結果是一樣的。


鏈表的結果、打印鏈表、初始化鏈表

struct binarytree
{
	int data;
	binarytree * lchild;
	binarytree * rchild;
};
void Create(binarytree * & t)//指針的引用
{
	int  c;
	cin>>c;
	if(c==-1)//遞歸的出口
		t=NULL;
	else
	{
		t=new binarytree;
		t->data=c;
		Create(t->lchild);//遞歸左子節點
		Create(t->rchild);//遞歸右子節點
	}
}
void Preprint(binarytree *head)//中序遍歷
{
	if(head==NULL)
		return;
	cout<<head->data<<" ";
	Preprint(head->lchild);
	Preprint(head->rchild);
}
初試化過程中輸入-1,相當於輸入了空樹。所以當輸入1 2 -1 -1  3  -1  -1.此二叉樹的中序遍歷就是1 2 3。

測試程序:

#include<iostream>
using namespace std;
#include<queue>
int main()
{
	binarytree *head;
	Create(head);
	cout<<"鏡像前二叉樹的中序遍歷:"<<endl;
	Preprint(head);
	cout<<endl;

	MirrorRecursively(head);
	cout<<"使用遞歸法鏡像後二叉樹的中序遍歷:"<<endl;
	Preprint(head);
	cout<<endl;

	MirrorLoopLy(head);
	cout<<"使用循環法鏡像後二叉樹的中序遍歷:"<<endl;
	Preprint(head);
	cout<<endl;
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章